mirror of
https://github.com/SoftEtherVPN/SoftEtherVPN.git
synced 2025-06-27 19:35:09 +03:00
v4.44-9807-rtm
This commit is contained in:
parent
556bc0afe2
commit
ed17437af9
@ -13190,7 +13190,6 @@ void InRpcEnumLink(RPC_ENUM_LINK *t, PACK *p)
|
||||
e->ConnectedTime = PackGetInt64Ex(p, "ConnectedTime", i);
|
||||
e->Connected = PackGetBoolEx(p, "Connected", i);
|
||||
e->LastError = PackGetIntEx(p, "LastError", i);
|
||||
PackGetStrEx(p, "LinkHubName", e->HubName, sizeof(e->HubName), i);
|
||||
}
|
||||
}
|
||||
void OutRpcEnumLink(PACK *p, RPC_ENUM_LINK *t)
|
||||
|
@ -126,10 +126,10 @@
|
||||
|
||||
|
||||
// Version number
|
||||
#define CEDAR_VER 443
|
||||
#define CEDAR_VER 444
|
||||
|
||||
// Build Number
|
||||
#define CEDAR_BUILD 9799
|
||||
#define CEDAR_BUILD 9807
|
||||
|
||||
// Beta number
|
||||
//#define BETA_NUMBER 3
|
||||
@ -148,12 +148,12 @@
|
||||
#endif // BUILD_PLACE
|
||||
|
||||
// Specifies the build date
|
||||
#define BUILD_DATE_Y 2023
|
||||
#define BUILD_DATE_M 8
|
||||
#define BUILD_DATE_D 31
|
||||
#define BUILD_DATE_HO 10
|
||||
#define BUILD_DATE_Y 2025
|
||||
#define BUILD_DATE_M 4
|
||||
#define BUILD_DATE_D 16
|
||||
#define BUILD_DATE_HO 4
|
||||
#define BUILD_DATE_MI 30
|
||||
#define BUILD_DATE_SE 0
|
||||
#define BUILD_DATE_SE 26
|
||||
|
||||
// Tolerable time difference
|
||||
#define ALLOW_TIMESTAMP_DIFF (UINT64)(3 * 24 * 60 * 60 * 1000)
|
||||
|
@ -196,6 +196,8 @@ void CheckNetworkAcceptThread(THREAD *thread, void *param)
|
||||
|
||||
Disconnect(s);
|
||||
ReleaseSock(s);
|
||||
|
||||
Free(c);
|
||||
}
|
||||
|
||||
|
||||
@ -239,15 +241,16 @@ void CheckNetworkListenThread(THREAD *thread, void *param)
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_NETWORK_2 c;
|
||||
CHECK_NETWORK_2 *c;
|
||||
THREAD *t;
|
||||
|
||||
Zero(&c, sizeof(c));
|
||||
c.s = new_sock;
|
||||
c.k = pri;
|
||||
c.x = x;
|
||||
c = ZeroMalloc(sizeof(CHECK_NETWORK_2));
|
||||
c->s = new_sock;
|
||||
c->k = pri;
|
||||
c->x = x;
|
||||
|
||||
t = NewThread(CheckNetworkAcceptThread, &c);
|
||||
t = NewThread(CheckNetworkAcceptThread, c);
|
||||
Insert(o, t);
|
||||
}
|
||||
}
|
||||
@ -14986,7 +14989,7 @@ bool ParseTcpState(char *src, bool *check_tcp_state, bool *established)
|
||||
|
||||
if (IsEmptyStr(src) == false)
|
||||
{
|
||||
if (StartWith("Established", src) == 0)
|
||||
if (StartWith("Established", src))
|
||||
{
|
||||
if(ok != false)
|
||||
{
|
||||
@ -14994,7 +14997,7 @@ bool ParseTcpState(char *src, bool *check_tcp_state, bool *established)
|
||||
*established = true;
|
||||
}
|
||||
}
|
||||
else if (StartWith("Unestablished", src) == 0)
|
||||
else if (StartWith("Unestablished", src))
|
||||
{
|
||||
if(ok != false)
|
||||
{
|
||||
|
@ -5336,7 +5336,10 @@ L_SKIP_TO_DISCARD:
|
||||
{
|
||||
PKT *pkt2 = ParsePacket(data, size);
|
||||
|
||||
DeleteIPv6DefaultRouterInRA(pkt2);
|
||||
if (pkt2 != NULL)
|
||||
{
|
||||
DeleteIPv6DefaultRouterInRA(pkt2);
|
||||
}
|
||||
|
||||
FreePacket(pkt2);
|
||||
}
|
||||
@ -5680,6 +5683,11 @@ void StorePacketToHubPa(HUB_PA *dest, SESSION *src, void *data, UINT size, PKT *
|
||||
// Remove the default router specification from the IPv6 router advertisement
|
||||
bool DeleteIPv6DefaultRouterInRA(PKT *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p->TypeL3 == L3_IPV6 && p->TypeL4 == L4_ICMPV6 &&
|
||||
(p->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_ROUTER_ADVERTISEMENT))
|
||||
{
|
||||
|
@ -381,6 +381,7 @@ struct HUB
|
||||
char RadiusRealm[MAX_SIZE]; // Radius realm (optional)
|
||||
bool RadiusConvertAllMsChapv2AuthRequestToEap; // Convert all MS-CHAPv2 auth request to EAP
|
||||
bool RadiusUsePeapInsteadOfEap; // Use PEAP instead of EAP
|
||||
bool RadiusRequireMessageAuthenticator; // Enforce use the Message-Authenticator attribute when non-EAP auth request and response
|
||||
volatile bool Halt; // Halting flag
|
||||
bool Offline; // Offline
|
||||
bool BeingOffline; // Be Doing Offline
|
||||
|
@ -597,36 +597,15 @@ void ProcIPsecEspPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
|
||||
ipsec_sa = SearchClientToServerIPsecSaBySpi(ike, spi);
|
||||
if (ipsec_sa == NULL)
|
||||
{
|
||||
// Invalid SPI
|
||||
UINT64 init_cookie = Rand64();
|
||||
UINT64 resp_cookie = 0;
|
||||
IKE_CLIENT *c = NULL;
|
||||
IKE_CLIENT t;
|
||||
|
||||
|
||||
Copy(&t.ClientIP, &p->SrcIP, sizeof(IP));
|
||||
t.ClientPort = p->SrcPort;
|
||||
Copy(&t.ServerIP, &p->DstIP, sizeof(IP));
|
||||
t.ServerPort = p->DestPort;
|
||||
t.CurrentIkeSa = NULL;
|
||||
|
||||
if (p->DestPort == IPSEC_PORT_IPSEC_ESP_RAW)
|
||||
{
|
||||
t.ClientPort = t.ServerPort = IPSEC_PORT_IPSEC_ISAKMP;
|
||||
}
|
||||
|
||||
c = Search(ike->ClientList, &t);
|
||||
|
||||
if (c != NULL && c->CurrentIkeSa != NULL)
|
||||
{
|
||||
init_cookie = c->CurrentIkeSa->InitiatorCookie;
|
||||
resp_cookie = c->CurrentIkeSa->ResponderCookie;
|
||||
}
|
||||
|
||||
SendInformationalExchangePacketEx(ike, (c == NULL ? &t : c), IkeNewNoticeErrorInvalidSpiPayload(spi), false,
|
||||
init_cookie, resp_cookie);
|
||||
|
||||
SendDeleteIPsecSaPacket(ike, (c == NULL ? &t : c), spi);
|
||||
// Do nothing: see https://github.com/SoftEtherVPN/SoftEtherVPN/security/advisories/GHSA-j35p-p8pj-vqxq
|
||||
// RFC4303, in 3.4.2
|
||||
// If no valid Security Association exists for this packet, the receiver
|
||||
// MUST discard the packet; this is an auditable event. The audit log
|
||||
// entry for this event SHOULD include the SPI value, date/time
|
||||
// received, Source Address, Destination Address, Sequence Number, and
|
||||
// (in IPv6) the cleartext Flow ID.
|
||||
//
|
||||
// Thank you for phillibert, Amazon Web Services, Inc.
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,12 +294,39 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
|
||||
data = recv_packet->Data;
|
||||
size = recv_packet->DataSize;
|
||||
|
||||
if (size >= (c->MdRecv->Size + c->CipherDecrypt->IvSize + sizeof(UINT)))
|
||||
if(c->CipherDecrypt->IsAeadCipher)
|
||||
{
|
||||
UCHAR *tag;
|
||||
|
||||
// Update variable part (packet ID) of IV
|
||||
Copy(c->IvRecv, data, sizeof(recv_packet->PacketId));
|
||||
data += sizeof(UINT);
|
||||
size -= sizeof(UINT);
|
||||
|
||||
// tag data
|
||||
tag = data;
|
||||
if(size < OPENVPN_TAG_SIZE) goto decode_error;
|
||||
data += OPENVPN_TAG_SIZE;
|
||||
size -= OPENVPN_TAG_SIZE;
|
||||
|
||||
// Decryption
|
||||
if (size == 0 || (c->CipherDecrypt->BlockSize != 0 && (size % c->CipherDecrypt->BlockSize) != 0)) goto decode_error;
|
||||
size = CipherProcessAead(c->CipherDecrypt, c->IvRecv, tag, OPENVPN_TAG_SIZE, s->TmpBuf, data, size, c->IvRecv, sizeof(UINT));
|
||||
if (size == 0)
|
||||
{
|
||||
Debug("OvsDecrypt(): CipherProcessAead() failed!\n");
|
||||
goto decode_error;
|
||||
}
|
||||
data = s->TmpBuf;
|
||||
}
|
||||
else // Non AEAD cipher
|
||||
{
|
||||
UCHAR *hmac;
|
||||
UCHAR *iv;
|
||||
UCHAR hmac_test[128];
|
||||
|
||||
if (size < (c->MdRecv->Size + c->CipherDecrypt->IvSize + sizeof(UINT))) goto decode_error;
|
||||
|
||||
// HMAC
|
||||
hmac = data;
|
||||
data += c->MdRecv->Size;
|
||||
@ -307,67 +334,59 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
|
||||
|
||||
// Confirmation of HMAC
|
||||
MdProcess(c->MdRecv, hmac_test, data, size);
|
||||
if (Cmp(hmac_test, hmac, c->MdRecv->Size) == 0)
|
||||
if (Cmp(hmac_test, hmac, c->MdRecv->Size) != 0) goto decode_error;
|
||||
|
||||
// IV
|
||||
iv = data;
|
||||
data += c->CipherDecrypt->IvSize;
|
||||
size -= c->CipherDecrypt->IvSize;
|
||||
|
||||
// Decryption
|
||||
if (size == 0 || (c->CipherDecrypt->BlockSize != 0 && (size % c->CipherDecrypt->BlockSize) != 0)) goto decode_error;
|
||||
size = CipherProcess(c->CipherDecrypt, iv, s->TmpBuf, data, size);
|
||||
if(size == 0) goto decode_error;
|
||||
|
||||
data = s->TmpBuf;
|
||||
// Seek buffer after the packet ID
|
||||
data += sizeof(UINT);
|
||||
size -= sizeof(UINT);
|
||||
}
|
||||
|
||||
// Update of last communication time
|
||||
se->LastCommTick = s->Now;
|
||||
|
||||
if (size < sizeof(UINT)){
|
||||
goto decode_error;
|
||||
}
|
||||
|
||||
|
||||
if (size >= sizeof(ping_signature) &&
|
||||
Cmp(data, ping_signature, sizeof(ping_signature)) == 0)
|
||||
{
|
||||
// Ignore since a ping packet has been received
|
||||
DoNothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Receive a valid data packet!!
|
||||
if (se->Ipc != NULL)
|
||||
{
|
||||
// Update of last communication time
|
||||
se->LastCommTick = s->Now;
|
||||
|
||||
// IV
|
||||
iv = data;
|
||||
data += c->CipherDecrypt->IvSize;
|
||||
size -= c->CipherDecrypt->IvSize;
|
||||
|
||||
// Payload
|
||||
if (size >= 1 && (c->CipherDecrypt->BlockSize == 0 || (size % c->CipherDecrypt->BlockSize) == 0))
|
||||
switch (se->Mode)
|
||||
{
|
||||
UINT data_packet_id;
|
||||
case OPENVPN_MODE_L2: // Send an Ethernet packet to a session
|
||||
IPCSendL2(se->Ipc, data, size);
|
||||
break;
|
||||
|
||||
// Decryption
|
||||
size = CipherProcess(c->CipherDecrypt, iv, s->TmpBuf, data, size);
|
||||
|
||||
data = s->TmpBuf;
|
||||
|
||||
if (size >= sizeof(UINT))
|
||||
{
|
||||
data_packet_id = READ_UINT(data);
|
||||
|
||||
data += sizeof(UINT);
|
||||
size -= sizeof(UINT);
|
||||
|
||||
if (size >= sizeof(ping_signature) &&
|
||||
Cmp(data, ping_signature, sizeof(ping_signature)) == 0)
|
||||
{
|
||||
// Ignore since a ping packet has been received
|
||||
DoNothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Receive a packet!!
|
||||
if (se->Ipc != NULL)
|
||||
{
|
||||
switch (se->Mode)
|
||||
{
|
||||
case OPENVPN_MODE_L2: // Send an Ethernet packet to a session
|
||||
IPCSendL2(se->Ipc, data, size);
|
||||
break;
|
||||
|
||||
case OPENVPN_MODE_L3: // Send an IPv4 packet to a session
|
||||
IPCSendIPv4(se->Ipc, data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case OPENVPN_MODE_L3: // Send an IPv4 packet to a session
|
||||
IPCSendIPv4(se->Ipc, data, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Debug("HMAC Failed (c=%u)\n", c->KeyId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
decode_error:
|
||||
|
||||
OvsFreePacket(recv_packet);
|
||||
}
|
||||
@ -770,6 +789,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
|
||||
LIST *o;
|
||||
BUF *b;
|
||||
char opt_str[MAX_SIZE];
|
||||
char *cipher_name, *md_name;
|
||||
// Validate arguments
|
||||
if (s == NULL || se == NULL || c == NULL || data == NULL)
|
||||
{
|
||||
@ -871,14 +891,6 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
|
||||
}
|
||||
}
|
||||
|
||||
// Encryption algorithm
|
||||
c->CipherEncrypt = OvsGetCipher(IniStrValue(o, "cipher"));
|
||||
c->CipherDecrypt = NewCipher(c->CipherEncrypt->Name);
|
||||
|
||||
// Hash algorithm
|
||||
c->MdSend = OvsGetMd(IniStrValue(o, "auth"));
|
||||
c->MdRecv = NewMd(c->MdSend->Name);
|
||||
|
||||
// Random number generation
|
||||
Rand(c->ServerKey.Random1, sizeof(c->ServerKey.Random1));
|
||||
Rand(c->ServerKey.Random2, sizeof(c->ServerKey.Random2));
|
||||
@ -904,13 +916,45 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
|
||||
c->ExpansionKey, sizeof(c->ExpansionKey));
|
||||
FreeBuf(b);
|
||||
|
||||
// Set the key
|
||||
// Encryption algorithm
|
||||
cipher_name = IniStrValue(o, "cipher");
|
||||
c->CipherEncrypt = OvsGetCipher(cipher_name);
|
||||
c->CipherDecrypt = OvsGetCipher(cipher_name);
|
||||
SetCipherKey(c->CipherDecrypt, c->ExpansionKey + 0, false);
|
||||
SetCipherKey(c->CipherEncrypt, c->ExpansionKey + 128, true);
|
||||
SetMdKey(c->MdRecv, c->ExpansionKey + 64, c->MdRecv->Size);
|
||||
SetMdKey(c->MdSend, c->ExpansionKey + 192, c->MdSend->Size);
|
||||
|
||||
OvsFreeOptions(o);
|
||||
md_name = IniStrValue(o, "auth");
|
||||
if(c->CipherDecrypt->IsAeadCipher){
|
||||
// In AEAD mode the IV is composed by the packet ID and a part of the HMAC key
|
||||
Copy(c->IvRecv + sizeof(c->LastDataPacketId), c->ExpansionKey + 64, c->CipherDecrypt->IvSize - sizeof(c->LastDataPacketId));
|
||||
Copy(c->IvSend + sizeof(c->LastDataPacketId), c->ExpansionKey + 192, c->CipherEncrypt->IvSize - sizeof(c->LastDataPacketId));
|
||||
c->MdSend = NULL;
|
||||
c->MdRecv = NULL;
|
||||
}else{
|
||||
// Hash algorithm
|
||||
c->MdSend = OvsGetMd(md_name);
|
||||
c->MdRecv = OvsGetMd(md_name);
|
||||
SetMdKey(c->MdRecv, c->ExpansionKey + 64, c->MdRecv->Size);
|
||||
SetMdKey(c->MdSend, c->ExpansionKey + 192, c->MdSend->Size);
|
||||
}
|
||||
|
||||
// We pass the cipher name sent from the OpenVPN client, unless it's a different cipher, to prevent a message such as:
|
||||
// WARNING: 'cipher' is used inconsistently, local='cipher AES-128-GCM', remote='cipher aes-128-gcm'
|
||||
// It happens because OpenVPN uses "strcmp()" to compare the local and remote parameters:
|
||||
// https://github.com/OpenVPN/openvpn/blob/a6fd48ba36ede465b0905a95568c3ec0d425ca71/src/openvpn/options.c#L3819-L3831
|
||||
if (StrCmpi(cipher_name, c->CipherEncrypt->Name) != 0)
|
||||
{
|
||||
cipher_name = c->CipherEncrypt->Name;
|
||||
}
|
||||
|
||||
if(c->MdSend != NULL){
|
||||
if (StrCmpi(md_name, c->MdSend->Name) != 0)
|
||||
{
|
||||
md_name = c->MdSend->Name;
|
||||
}
|
||||
}else{
|
||||
md_name = "[null-digest]";
|
||||
}
|
||||
|
||||
// Generate the response option string
|
||||
Format(c->ServerKey.OptionString, sizeof(c->ServerKey.OptionString),
|
||||
@ -920,9 +964,11 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
|
||||
se->LinkMtu,
|
||||
se->TunMtu,
|
||||
c->Proto,
|
||||
c->CipherEncrypt->Name, c->MdSend->Name, c->CipherEncrypt->KeySize * 8);
|
||||
cipher_name, md_name, c->CipherEncrypt->KeySize * 8);
|
||||
Debug("Building OptionStr: %s\n", c->ServerKey.OptionString);
|
||||
|
||||
OvsFreeOptions(o);
|
||||
|
||||
OvsLog(s, se, c, "LO_OPTION_STR_SEND", c->ServerKey.OptionString);
|
||||
}
|
||||
|
||||
@ -931,7 +977,7 @@ CIPHER *OvsGetCipher(char *name)
|
||||
{
|
||||
CIPHER *c = NULL;
|
||||
|
||||
if (IsEmptyStr(name) == false && IsStrInStrTokenList(OPENVPN_CIPHER_LIST, name, NULL, false))
|
||||
if (IsEmptyStr(name) == false)
|
||||
{
|
||||
c = NewCipher(name);
|
||||
}
|
||||
@ -949,7 +995,7 @@ MD *OvsGetMd(char *name)
|
||||
{
|
||||
MD *m = NULL;
|
||||
|
||||
if (IsEmptyStr(name) == false && IsStrInStrTokenList(OPENVPN_MD_LIST, name, NULL, false))
|
||||
if (IsEmptyStr(name) == false)
|
||||
{
|
||||
m = NewMd(name);
|
||||
}
|
||||
@ -1419,7 +1465,8 @@ OPENVPN_CHANNEL *OvsNewChannel(OPENVPN_SESSION *se, UCHAR key_id)
|
||||
|
||||
c->KeyId = key_id;
|
||||
|
||||
Rand(c->NextIv, sizeof(c->NextIv));
|
||||
Rand(c->IvSend, sizeof(c->IvSend));
|
||||
Rand(c->IvRecv, sizeof(c->IvRecv));
|
||||
|
||||
//c->NextRekey = se->Server->Now + (UINT64)5000;
|
||||
|
||||
@ -1467,9 +1514,7 @@ UINT64 OvsNewServerSessionId(OPENVPN_SERVER *s)
|
||||
// Build and submit the OpenVPN data packet
|
||||
void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, void *data, UINT data_size)
|
||||
{
|
||||
UCHAR uc;
|
||||
UCHAR *encrypted_data;
|
||||
UINT encrypted_size;
|
||||
const UCHAR op = ((OPENVPN_P_DATA_V1 << 3) & 0xF8) | (key_id & 0x07);
|
||||
UCHAR *dest_data;
|
||||
UINT dest_size;
|
||||
UINT r;
|
||||
@ -1480,40 +1525,68 @@ void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, vo
|
||||
return;
|
||||
}
|
||||
|
||||
uc = ((OPENVPN_P_DATA_V1 << 3) & 0xF8) | (key_id & 0x07);
|
||||
|
||||
// Generate the data to be encrypted
|
||||
if (c->CipherEncrypt->IsAeadCipher){
|
||||
// [ opcode ] [ - packet ID - ] [ TAG ] [ * packet payload * ]
|
||||
UCHAR tag[16];
|
||||
UINT ret;
|
||||
|
||||
encrypted_size = sizeof(UINT) + data_size;
|
||||
encrypted_data = ZeroMalloc(encrypted_size);
|
||||
// Update variable part (packet ID) of IV
|
||||
WRITE_UINT(c->IvSend, data_packet_id);
|
||||
|
||||
WRITE_UINT(encrypted_data, data_packet_id);
|
||||
Copy(encrypted_data + sizeof(UINT), data, data_size);
|
||||
// Prepare a buffer to store the results
|
||||
dest_data = Malloc(sizeof(op) + sizeof(data_packet_id) + sizeof(tag) + data_size + 256);
|
||||
|
||||
// Prepare a buffer to store the results
|
||||
dest_data = Malloc(sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize + encrypted_size + 256);
|
||||
// Set data size to the maximum known
|
||||
dest_size = sizeof(op) + sizeof(data_packet_id) + sizeof(tag);
|
||||
|
||||
// Encrypt
|
||||
r = CipherProcess(c->CipherEncrypt, c->NextIv, dest_data + sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize,
|
||||
encrypted_data, encrypted_size);
|
||||
dest_size = sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize + r;
|
||||
// Write opcode
|
||||
dest_data[0] = op;
|
||||
|
||||
// Copy the IV
|
||||
Copy(dest_data + sizeof(UCHAR) + c->MdSend->Size, c->NextIv, c->CipherEncrypt->IvSize);
|
||||
// Write packet ID
|
||||
WRITE_UINT(dest_data + sizeof(op), data_packet_id);
|
||||
|
||||
// Calculate the HMAC
|
||||
MdProcess(c->MdSend, dest_data + sizeof(UCHAR), dest_data + sizeof(UCHAR) + c->MdSend->Size,
|
||||
dest_size - sizeof(UCHAR) - c->MdSend->Size);
|
||||
// Write encrypted payload
|
||||
ret = CipherProcessAead(c->CipherEncrypt, c->IvSend, tag, 16, dest_data + dest_size, data, data_size, c->IvSend, sizeof(data_packet_id));
|
||||
if (ret == 0)
|
||||
{
|
||||
Debug("OvsEncrypt(): CipherProcessAead() failed!\n");
|
||||
return;
|
||||
}
|
||||
dest_size += ret;
|
||||
|
||||
// Update the NextIV
|
||||
Copy(c->NextIv, dest_data + dest_size - c->CipherEncrypt->IvSize, c->CipherEncrypt->IvSize);
|
||||
// Write authentication tag
|
||||
Copy(dest_data + sizeof(op) + sizeof(data_packet_id), tag, sizeof(tag));
|
||||
}else{
|
||||
// [ opcode ] [ HMAC ] [ - IV - ] [ * packet ID * ] [ * packet payload * ]
|
||||
UINT encrypted_size = sizeof(data_packet_id) + data_size;
|
||||
UCHAR *encrypted_data = ZeroMalloc(encrypted_size);
|
||||
WRITE_UINT(encrypted_data, data_packet_id);
|
||||
Copy(encrypted_data + sizeof(data_packet_id), data, data_size);
|
||||
|
||||
// Op-code
|
||||
dest_data[0] = uc;
|
||||
// Prepare a buffer to store the results
|
||||
dest_data = Malloc(sizeof(op) + c->MdSend->Size + c->CipherEncrypt->IvSize + encrypted_size + 256);
|
||||
dest_data[0] = op;
|
||||
|
||||
// Encrypt
|
||||
r = CipherProcess(c->CipherEncrypt, c->IvSend, dest_data + sizeof(op) + c->MdSend->Size + c->CipherEncrypt->IvSize,
|
||||
encrypted_data, encrypted_size);
|
||||
Free(encrypted_data);
|
||||
|
||||
dest_size = sizeof(op) + c->MdSend->Size + c->CipherEncrypt->IvSize + r;
|
||||
|
||||
// Copy the IV
|
||||
Copy(dest_data + sizeof(op) + c->MdSend->Size, c->IvSend, c->CipherEncrypt->IvSize);
|
||||
|
||||
// Calculate the HMAC
|
||||
MdProcess(c->MdSend, dest_data + sizeof(op), dest_data + sizeof(op) + c->MdSend->Size,
|
||||
dest_size - sizeof(op) - c->MdSend->Size);
|
||||
|
||||
// Update the IV for next
|
||||
Copy(c->IvSend, dest_data + dest_size - c->CipherEncrypt->IvSize, c->CipherEncrypt->IvSize);
|
||||
}
|
||||
|
||||
OvsSendPacketRawNow(c->Server, c->Session, dest_data, dest_size);
|
||||
|
||||
Free(encrypted_data);
|
||||
}
|
||||
|
||||
// Build an OpenVPN control packet
|
||||
|
@ -118,6 +118,7 @@
|
||||
#define OPENVPN_MAX_SSL_RECV_BUF_SIZE (256 * 1024) // SSL receive buffer maximum length
|
||||
|
||||
#define OPENVPN_MAX_KEY_SIZE 64 // Maximum key size
|
||||
#define OPENVPN_TAG_SIZE 16 // Tag size (for packet authentication in AEAD mode)
|
||||
|
||||
#define OPENVPN_TMP_BUFFER_SIZE (65536 + 256) // Temporary buffer size
|
||||
|
||||
@ -142,12 +143,6 @@
|
||||
#define OPENVPN_IPC_POSTFIX_L2 "OPENVPN_L2"
|
||||
#define OPENVPN_IPC_POSTFIX_L3 "OPENVPN_L3"
|
||||
|
||||
// List of supported encryption algorithms
|
||||
#define OPENVPN_CIPHER_LIST "[NULL-CIPHER] NULL AES-128-CBC AES-192-CBC AES-256-CBC BF-CBC CAST-CBC CAST5-CBC DES-CBC DES-EDE-CBC DES-EDE3-CBC DESX-CBC RC2-40-CBC RC2-64-CBC RC2-CBC CAMELLIA-128-CBC CAMELLIA-192-CBC CAMELLIA-256-CBC"
|
||||
|
||||
// List of the supported hash algorithm
|
||||
#define OPENVPN_MD_LIST "SHA SHA1 SHA256 SHA384 SHA512 MD5 MD4 RMD160"
|
||||
|
||||
// MTU
|
||||
#define OPENVPN_MTU_LINK 1514 // Ethernet MTU
|
||||
#define OPENVPN_MTU_TUN 1500 // Tun MTU
|
||||
@ -163,6 +158,7 @@
|
||||
#define OPENVPN_P_DATA_V1 6 // Data packet
|
||||
#define OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2 7 // Connection request from client
|
||||
#define OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2 8 // Connection response from server
|
||||
#define OPENVPN_P_DATA_V2 9 // Data packet v2
|
||||
|
||||
// State of OpenVPN channel
|
||||
#define OPENVPN_CHANNEL_STATUS_INIT 0 // Initialization phase
|
||||
@ -240,9 +236,10 @@ struct OPENVPN_CHANNEL
|
||||
CIPHER *CipherDecrypt; // Decryption algorithm
|
||||
MD *MdSend; // Transmission MD algorithm
|
||||
MD *MdRecv; // Reception MD algorithm
|
||||
UCHAR IvSend[64]; // Transmission IV
|
||||
UCHAR IvRecv[64]; // Reception IV
|
||||
UCHAR MasterSecret[48]; // Master Secret
|
||||
UCHAR ExpansionKey[256]; // Expansion Key
|
||||
UCHAR NextIv[64]; // Next IV
|
||||
UINT LastDataPacketId; // Previous Data Packet ID
|
||||
UINT64 EstablishedTick; // Established time
|
||||
UCHAR KeyId; // KEY ID
|
||||
|
@ -1721,7 +1721,7 @@ LABEL_ERROR:
|
||||
|
||||
// Attempts Radius authentication (with specifying retry interval and multiple server)
|
||||
bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20,
|
||||
RADIUS_LOGIN_OPTION *opt, char *hubname)
|
||||
RADIUS_LOGIN_OPTION *opt, char *hubname, bool RadiusRequireMessageAuthenticator)
|
||||
{
|
||||
UCHAR random[MD5_SIZE];
|
||||
UCHAR id;
|
||||
@ -1890,6 +1890,10 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
|
||||
USHORT sz = 0;
|
||||
UINT pos = 0;
|
||||
BOOL *finish = ZeroMallocEx(sizeof(BOOL) * LIST_NUM(ip_list), true);
|
||||
// Message-Authenticator
|
||||
UCHAR zero16[16] = {0};
|
||||
UCHAR msg_auth[16] = {0};
|
||||
UINT msg_auth_pos = 0;
|
||||
|
||||
Zero(tmp, sizeof(tmp));
|
||||
|
||||
@ -2015,9 +2019,27 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
|
||||
RadiusAddValue(p, RADIUS_ATTRIBUTE_PROXY_STATE, 0, 0, opt->In_VpnProtocolState, StrLen(opt->In_VpnProtocolState));
|
||||
}
|
||||
|
||||
SeekBuf(p, 0, 0);
|
||||
if (RadiusRequireMessageAuthenticator == false)
|
||||
{
|
||||
SeekBuf(p, 0, 0);
|
||||
|
||||
WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size);
|
||||
WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Message-Authenticator zero-filled
|
||||
msg_auth_pos = p->Current;
|
||||
Zero(zero16, sizeof(zero16));
|
||||
RadiusAddValue(p, RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR, 0, 0, zero16, sizeof(zero16));
|
||||
|
||||
// Length
|
||||
SeekBuf(p, 0, 0);
|
||||
WRITE_USHORT(((UCHAR *)p->Buf) + 2, (USHORT)p->Size);
|
||||
|
||||
// generate Message-Authenticator value
|
||||
HMacMd5(msg_auth, secret, secret_size, p->Buf, p->Size);
|
||||
Copy( ((UCHAR *)p->Buf) + msg_auth_pos + 2, msg_auth, 16 );
|
||||
}
|
||||
|
||||
// Create a socket
|
||||
sock = NewUDPEx(0, IsIP6(LIST_DATA(ip_list, pos)));
|
||||
@ -2108,7 +2130,22 @@ RECV_RETRY:
|
||||
LIST *o;
|
||||
BUF *buf = NewBufFromMemory(recv_buf, recv_size);
|
||||
|
||||
ret = true;
|
||||
if (RadiusRequireMessageAuthenticator == false)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Validate Response Authenticator header and Message-Authenticator
|
||||
if ( recv_size < 20 )
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RadiusValidateAuthenticator(buf, (char *)secret, (char *)random, RadiusRequireMessageAuthenticator);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_mschap && mschap_v2_server_response_20 != NULL)
|
||||
{
|
||||
@ -2221,6 +2258,156 @@ RECV_RETRY:
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Validate Response Authenticator header and Message-Authenticator
|
||||
bool RadiusValidateAuthenticator(BUF *b, char *secret, char *request_authenticator, bool RadiusRequireMessageAuthenticator)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
BUF *tmp = CloneBuf(b);
|
||||
LIST *o;
|
||||
|
||||
UCHAR code;
|
||||
UCHAR id;
|
||||
USHORT len;
|
||||
UCHAR auth0[16];
|
||||
UCHAR auth1[16];
|
||||
UINT avp_pos = 0;
|
||||
|
||||
// read header from the buffer
|
||||
if (tmp == NULL)
|
||||
{
|
||||
FreeBuf(tmp);
|
||||
return false;
|
||||
}
|
||||
if ( tmp->Size < 20 )
|
||||
{
|
||||
FreeBuf(tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
ReadBuf(tmp, &code, 1);
|
||||
ReadBuf(tmp, &id, 1);
|
||||
len = 0;
|
||||
ReadBuf(tmp, &len, 2);
|
||||
len = Endian16(len);
|
||||
ReadBuf(tmp, auth0, 16);
|
||||
|
||||
avp_pos = tmp->Current;
|
||||
|
||||
if ( tmp->Size != len )
|
||||
{
|
||||
FreeBuf(tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate Response Authenticator header
|
||||
Copy( ((UCHAR *)tmp->Buf) + tmp->Current - 16 , request_authenticator, 16 );
|
||||
SeekBufToEnd( tmp );
|
||||
WriteBuf( tmp, secret, StrLen(secret) );
|
||||
|
||||
Md5( auth1, tmp->Buf, tmp->Size );
|
||||
|
||||
if (Cmp(auth0, auth1, 16) != 0)
|
||||
{
|
||||
FreeBuf(tmp);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// Validate Response Message-Authenticator
|
||||
SeekBufToBegin(tmp);
|
||||
o = RadiusParseOptions(tmp);
|
||||
|
||||
if (o != NULL)
|
||||
{
|
||||
DHCP_OPTION *msg_authenticator = GetDhcpOption(o, RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR);
|
||||
|
||||
if (msg_authenticator != NULL)
|
||||
{
|
||||
|
||||
tmp->Current = avp_pos;
|
||||
while (true)
|
||||
{
|
||||
UCHAR attribute_id;
|
||||
UCHAR size;
|
||||
UCHAR data[256];
|
||||
|
||||
if (ReadBuf(tmp, &attribute_id, 1) != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (ReadBuf(tmp, &size, 1) != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (size <= 2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
size -= 2;
|
||||
if (ReadBuf(tmp, data, size) != size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( attribute_id == (UCHAR)RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR )
|
||||
{
|
||||
UCHAR zero16[16];
|
||||
UCHAR msg_auth0[16];
|
||||
UCHAR msg_auth1[16];
|
||||
|
||||
Copy(msg_auth0, data, size);
|
||||
|
||||
Zero(zero16, sizeof(zero16));
|
||||
Copy( ((UCHAR *)tmp->Buf) + tmp->Current - sizeof(zero16), zero16, sizeof(zero16) );
|
||||
|
||||
HMacMd5(msg_auth1, secret, StrLen(secret), tmp->Buf, tmp->Size - StrLen(secret));
|
||||
|
||||
if (Cmp(msg_auth0, msg_auth1, 16) == 0)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( RadiusRequireMessageAuthenticator )
|
||||
{
|
||||
// RadiusRequireMessageAuthenticator == true, Message-Authenticator attribute is missing
|
||||
FreeBuf(tmp);
|
||||
FreeDhcpOptions(o);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else if ( RadiusRequireMessageAuthenticator )
|
||||
{
|
||||
// RadiusRequireMessageAuthenticator == true , avp is missing
|
||||
FreeBuf(tmp);
|
||||
FreeDhcpOptions(o);
|
||||
return false;
|
||||
}
|
||||
|
||||
FreeBuf(tmp);
|
||||
FreeDhcpOptions(o);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Parse RADIUS attributes
|
||||
LIST *RadiusParseOptions(BUF *b)
|
||||
{
|
||||
|
@ -375,13 +375,14 @@ struct RADIUS_LOGIN_OPTION
|
||||
|
||||
// Function prototype
|
||||
bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT secret_size, wchar_t *username, char *password, UINT interval, UCHAR *mschap_v2_server_response_20,
|
||||
RADIUS_LOGIN_OPTION *opt, char *hubname);
|
||||
RADIUS_LOGIN_OPTION *opt, char *hubname, bool RadiusRequireMessageAuthenticator);
|
||||
BUF *RadiusEncryptPassword(char *password, UCHAR *random, UCHAR *secret, UINT secret_size);
|
||||
BUF *RadiusCreateUserName(wchar_t *username);
|
||||
BUF *RadiusCreateUserPassword(void *data, UINT size);
|
||||
BUF *RadiusCreateNasId(char *name);
|
||||
void RadiusAddValue(BUF *b, UCHAR t, UINT v, UCHAR vt, void *data, UINT size);
|
||||
LIST *RadiusParseOptions(BUF *b);
|
||||
bool RadiusValidateAuthenticator(BUF *b, char *secret, char *request_authenticator, bool RadiusRequireMessageAuthenticator);
|
||||
|
||||
#endif // RADIUS_H
|
||||
|
||||
|
@ -269,7 +269,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
|
||||
// Attempt to login
|
||||
b = RadiusLogin(c, radius_server_addr, radius_server_port,
|
||||
radius_secret, StrLen(radius_secret),
|
||||
name, password, interval, mschap_v2_server_response_20, opt, hub->Name);
|
||||
name, password, interval, mschap_v2_server_response_20, opt, hub->Name, hub->RadiusRequireMessageAuthenticator);
|
||||
|
||||
if (b)
|
||||
{
|
||||
|
@ -5060,6 +5060,7 @@ void SiWriteHubCfg(FOLDER *f, HUB *h)
|
||||
|
||||
CfgAddBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap", h->RadiusConvertAllMsChapv2AuthRequestToEap);
|
||||
CfgAddBool(f, "RadiusUsePeapInsteadOfEap", h->RadiusUsePeapInsteadOfEap);
|
||||
CfgAddBool(f, "RadiusRequireMessageAuthenticator", h->RadiusRequireMessageAuthenticator);
|
||||
}
|
||||
Unlock(h->RadiusOptionLock);
|
||||
|
||||
@ -5229,6 +5230,7 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
|
||||
|
||||
h->RadiusConvertAllMsChapv2AuthRequestToEap = CfgGetBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap");
|
||||
h->RadiusUsePeapInsteadOfEap = CfgGetBool(f, "RadiusUsePeapInsteadOfEap");
|
||||
h->RadiusRequireMessageAuthenticator = CfgGetBool(f, "RadiusRequireMessageAuthenticator");
|
||||
|
||||
if (interval == 0)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
BUILD_NUMBER 9799
|
||||
VERSION 443
|
||||
BUILD_NAME beta
|
||||
BUILD_DATE 20230831_103000
|
||||
BUILD_NUMBER 9807
|
||||
VERSION 444
|
||||
BUILD_NAME rtm
|
||||
BUILD_DATE 20250416_043026
|
||||
|
@ -1307,6 +1307,7 @@ CIPHER *NewCipher(char *name)
|
||||
EVP_CIPHER_CTX_init(c->Ctx);
|
||||
#endif
|
||||
|
||||
c->IsAeadCipher = (EVP_CIPHER_flags(c->Cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0;
|
||||
c->BlockSize = EVP_CIPHER_block_size(c->Cipher);
|
||||
c->KeySize = EVP_CIPHER_key_length(c->Cipher);
|
||||
c->IvSize = EVP_CIPHER_iv_length(c->Cipher);
|
||||
@ -1371,6 +1372,74 @@ UINT CipherProcess(CIPHER *c, void *iv, void *dest, void *src, UINT size)
|
||||
return r + r2;
|
||||
}
|
||||
|
||||
// Process encryption / decryption (AEAD)
|
||||
UINT CipherProcessAead(CIPHER *c, void *iv, void *tag, UINT tag_size, void *dest, void *src, UINT src_size, void *aad, UINT aad_size)
|
||||
{
|
||||
int r = src_size;
|
||||
int r2 = 0;
|
||||
// Validate arguments
|
||||
if (c == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (c->IsNullCipher)
|
||||
{
|
||||
Copy(dest, src, src_size);
|
||||
return src_size;
|
||||
}
|
||||
else if (c->IsAeadCipher == false || iv == NULL || tag == NULL || tag_size == 0 || dest == NULL || src == NULL || src_size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_CipherInit_ex(c->Ctx, NULL, NULL, NULL, iv, c->Encrypt) == false)
|
||||
{
|
||||
Debug("CipherProcessAead(): EVP_CipherInit_ex() failed with error: %s\n", ERR_error_string(ERR_get_error(),NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c->Encrypt == false)
|
||||
{
|
||||
if (EVP_CIPHER_CTX_ctrl(c->Ctx, EVP_CTRL_AEAD_SET_TAG, tag_size, tag) == false)
|
||||
{
|
||||
Debug("CipherProcessAead(): EVP_CIPHER_CTX_ctrl() failed to set the tag!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (aad != NULL && aad_size != 0)
|
||||
{
|
||||
if (EVP_CipherUpdate(c->Ctx, NULL, &r, aad, aad_size) == false)
|
||||
{
|
||||
Debug("CipherProcessAead(): EVP_CipherUpdate() failed with error: %s\n", ERR_error_string(ERR_get_error(),NULL));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (EVP_CipherUpdate(c->Ctx, dest, &r, src, src_size) == false)
|
||||
{
|
||||
Debug("CipherProcessAead(): EVP_CipherUpdate() failed with error: %s\n", ERR_error_string(ERR_get_error(),NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (EVP_CipherFinal_ex(c->Ctx, ((UCHAR *)dest) + (UINT)r, &r2) == false)
|
||||
{
|
||||
Debug("CipherProcessAead(): EVP_CipherFinal_ex() failed with error: %s\n", ERR_error_string(ERR_get_error(),NULL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c->Encrypt)
|
||||
{
|
||||
if (EVP_CIPHER_CTX_ctrl(c->Ctx, EVP_CTRL_AEAD_GET_TAG, tag_size, tag) == false)
|
||||
{
|
||||
Debug("CipherProcessAead(): EVP_CIPHER_CTX_ctrl() failed to get the tag!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return r + r2;
|
||||
}
|
||||
|
||||
// Release of the cipher object
|
||||
void FreeCipher(CIPHER *c)
|
||||
{
|
||||
|
@ -354,7 +354,7 @@ struct DH_CTX
|
||||
struct CIPHER
|
||||
{
|
||||
char Name[MAX_PATH];
|
||||
bool IsNullCipher;
|
||||
bool IsNullCipher, IsAeadCipher;
|
||||
const struct evp_cipher_st *Cipher;
|
||||
struct evp_cipher_ctx_st *Ctx;
|
||||
bool Encrypt;
|
||||
@ -631,6 +631,7 @@ CIPHER *NewCipher(char *name);
|
||||
void FreeCipher(CIPHER *c);
|
||||
void SetCipherKey(CIPHER *c, void *key, bool enc);
|
||||
UINT CipherProcess(CIPHER *c, void *iv, void *dest, void *src, UINT size);
|
||||
UINT CipherProcessAead(CIPHER *c, void *iv, void *tag, UINT tag_size, void *dest, void *src, UINT src_size, void *aad, UINT aad_size);
|
||||
|
||||
MD *NewMd(char *name);
|
||||
void FreeMd(MD *md);
|
||||
|
@ -3036,13 +3036,20 @@ UINT UniToInt(wchar_t *str)
|
||||
void UniToStrForSingleChars(char *dst, UINT dst_size, wchar_t *src)
|
||||
{
|
||||
UINT i;
|
||||
UINT size;
|
||||
// Validate arguments
|
||||
if (dst == NULL || src == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0;i < UniStrLen(src) + 1;i++)
|
||||
size = UniStrLen(src) + 1;
|
||||
if (dst_size >= 1 && dst_size < size)
|
||||
{
|
||||
size = dst_size;
|
||||
}
|
||||
|
||||
for (i = 0;i < size;i++)
|
||||
{
|
||||
wchar_t s = src[i];
|
||||
char d;
|
||||
@ -3060,6 +3067,11 @@ void UniToStrForSingleChars(char *dst, UINT dst_size, wchar_t *src)
|
||||
d = ' ';
|
||||
}
|
||||
|
||||
if (i == (size - 1))
|
||||
{
|
||||
d = 0;
|
||||
}
|
||||
|
||||
dst[i] = d;
|
||||
}
|
||||
}
|
||||
|
@ -83,9 +83,19 @@ $TAG_BEFORE_REMOTE$remote $TAG_HOSTNAME$ $TAG_PORT$
|
||||
# cipher: [NULL-CIPHER] NULL AES-128-CBC AES-192-CBC AES-256-CBC BF-CBC
|
||||
# CAST-CBC CAST5-CBC DES-CBC DES-EDE-CBC DES-EDE3-CBC DESX-CBC
|
||||
# RC2-40-CBC RC2-64-CBC RC2-CBC CAMELLIA-128-CBC CAMELLIA-192-CBC CAMELLIA-256-CBC
|
||||
# data-ciphers: same as cipher
|
||||
# auth: SHA SHA1 SHA256 SHA384 SHA512 MD5 MD4 RMD160
|
||||
#
|
||||
# Note: To solve OpenVPN compatibility bug
|
||||
# Recent versions of the OpenVPN app require specifying the "data-ciphers"
|
||||
# field instead of the "cipher" field. However, older versions of the OpenVPN app
|
||||
# do not recognize "data-ciphers." Rather than ignoring it, they produce
|
||||
# a startup error stating that "no such option exists." This is a bug
|
||||
# in OpenVPN. If you encounter this issue, please comment out
|
||||
# the "data-ciphers" line.
|
||||
|
||||
cipher AES-128-CBC
|
||||
data-ciphers AES-128-CBC
|
||||
auth SHA1
|
||||
|
||||
|
||||
|
@ -730,7 +730,7 @@ POL_EX_18 对有此策略设置的会话,限制虚拟路由器上由内至
|
||||
POL_19 拒绝更改密码
|
||||
POL_EX_19 有此密码验证策略设置的用户将无法在 VPN Client 管理器上进行密码的更换。
|
||||
POL_20 最大多重登录数
|
||||
POL_EX_20 有此策略设置的用户无法进行多于设置数的并发登录数。 网桥模式会话不适用于此策略。此安全策略仅在 VPN Server 3.0 或以上版本,或具有多重登录限制功能的 VPN Server 2.0 版上有效。
|
||||
POL_EX_20 有此策略设置的用户无法进行多于设置数的并发登录数。 此安全策略仅在 VPN Server 3.0 或以上版本,或具有多重登录限制功能的 VPN Server 2.0 版上有效。
|
||||
POL_21 禁止 VoIP / QoS 功能
|
||||
POL_EX_21 有此策略设置的用户,无法在 VPN 连接会话中使用VoIP / QoS功能。此安全策略仅在 VPN Server 3.0 或以上版本,或具有 VoIP / QoS 功能的 VPN Server 2.0 版上有效。
|
||||
|
||||
|
@ -723,7 +723,7 @@ POL_EX_18 For sessions with this policy setting, this limits the traffic band
|
||||
POL_19 Deny Changing Password
|
||||
POL_EX_19 The users which use password authentication with this policy setting are not allowed to change their own password from the VPN Client Manager or similar.
|
||||
POL_20 Maximum Number of Multiple Logins
|
||||
POL_EX_20 Users with this policy setting are unable to have more than this number of concurrent logins. Bridge Mode sessions are not subjects to this policy. This security policy is only available on VPN Server 3.0 or greater, or VPN Server 2.0 with the multi-login restriction function.
|
||||
POL_EX_20 Users with this policy setting are unable to have more than this number of concurrent logins. This security policy is only available on VPN Server 3.0 or greater, or VPN Server 2.0 with the multi-login restriction function.
|
||||
POL_21 Deny VoIP / QoS Function
|
||||
POL_EX_21 Users with this security policy are unable to use VoIP / QoS functions in VPN connection sessions. This security policy is only available on VPN Server 3.0 or greater, or VPN Server 2.0 with the VoIP / QoS functions.
|
||||
|
||||
|
@ -726,7 +726,7 @@ POL_EX_18 このポリシーが設定されているセッションにおけ
|
||||
POL_19 ユーザーはパスワードを変更できない
|
||||
POL_EX_19 このポリシーが設定されているユーザーがパスワード認証の場合、ユーザーが VPN クライアント接続マネージャなどから自分のパスワードを変更することを禁止します。
|
||||
POL_20 多重ログイン制限数
|
||||
POL_EX_20 このポリシーが設定されているユーザーが設定されている数以上の同時ログインを行うことを禁止します。ブリッジモードセッションにはこの制限は適用されません。このセキュリティポリシーは、VPN Server 3.0 以降、または多重ログイン制限機能が搭載されている VPN Server 2.0 でのみ有効です。
|
||||
POL_EX_20 このポリシーが設定されているユーザーが設定されている数以上の同時ログインを行うことを禁止します。このセキュリティポリシーは、VPN Server 3.0 以降、または多重ログイン制限機能が搭載されている VPN Server 2.0 でのみ有効です。
|
||||
POL_21 VoIP / QoS 対応機能の使用を禁止
|
||||
POL_EX_21 このポリシーが設定されているユーザーの VPN 接続セッションにおいて VoIP / QoS 対応機能の使用を禁止します。このセキュリティポリシーは、VPN Server 3.0 以降、または VoIP / QoS 対応機能が搭載されている VPN Server 2.0 でのみ有効です。
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SoftEther VPN Source Code
|
||||
#
|
||||
# Copyright (c) 2012-2023 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2023 Daiyuu Nobori.
|
||||
# Copyright (c) 2012-2025 SoftEther VPN Project at University of Tsukuba, Japan.
|
||||
# Copyright (c) 2012-2025 Daiyuu Nobori.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# https://www.softether.org/
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 7.00.0500 */
|
||||
/* at Thu Aug 31 10:30:18 2023
|
||||
/* at Wed Apr 16 04:30:42 2025
|
||||
*/
|
||||
/* Compiler settings for .\vpnweb.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 7.00.0500 */
|
||||
/* at Thu Aug 31 10:30:18 2023
|
||||
/* at Wed Apr 16 04:30:42 2025
|
||||
*/
|
||||
/* Compiler settings for .\vpnweb.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 7.00.0500 */
|
||||
/* at Thu Aug 31 10:30:18 2023
|
||||
/* at Wed Apr 16 04:30:42 2025
|
||||
*/
|
||||
/* Compiler settings for .\vpnweb.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
|
Loading…
Reference in New Issue
Block a user