diff --git a/src/Cedar/Admin.c b/src/Cedar/Admin.c index ecb17e0c..f621c5c4 100644 --- a/src/Cedar/Admin.c +++ b/src/Cedar/Admin.c @@ -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) diff --git a/src/Cedar/Cedar.h b/src/Cedar/Cedar.h index 77b0a77b..1add063b 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -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) diff --git a/src/Cedar/Command.c b/src/Cedar/Command.c index 2a4cec46..c22a9825 100644 --- a/src/Cedar/Command.c +++ b/src/Cedar/Command.c @@ -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) { diff --git a/src/Cedar/Hub.c b/src/Cedar/Hub.c index a4da47b6..285807ac 100644 --- a/src/Cedar/Hub.c +++ b/src/Cedar/Hub.c @@ -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)) { diff --git a/src/Cedar/Hub.h b/src/Cedar/Hub.h index d9af78ef..bb88dab9 100644 --- a/src/Cedar/Hub.h +++ b/src/Cedar/Hub.h @@ -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 diff --git a/src/Cedar/IPsec_IKE.c b/src/Cedar/IPsec_IKE.c index f5b7943e..7d9ae35f 100644 --- a/src/Cedar/IPsec_IKE.c +++ b/src/Cedar/IPsec_IKE.c @@ -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; } diff --git a/src/Cedar/Interop_OpenVPN.c b/src/Cedar/Interop_OpenVPN.c index c4280394..c7957580 100644 --- a/src/Cedar/Interop_OpenVPN.c +++ b/src/Cedar/Interop_OpenVPN.c @@ -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 diff --git a/src/Cedar/Interop_OpenVPN.h b/src/Cedar/Interop_OpenVPN.h index 59a03b30..a366e64e 100644 --- a/src/Cedar/Interop_OpenVPN.h +++ b/src/Cedar/Interop_OpenVPN.h @@ -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 diff --git a/src/Cedar/Radius.c b/src/Cedar/Radius.c index bcbac5d4..d7437d35 100644 --- a/src/Cedar/Radius.c +++ b/src/Cedar/Radius.c @@ -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) { diff --git a/src/Cedar/Radius.h b/src/Cedar/Radius.h index 712b6003..a45bd89e 100644 --- a/src/Cedar/Radius.h +++ b/src/Cedar/Radius.h @@ -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 diff --git a/src/Cedar/Sam.c b/src/Cedar/Sam.c index 1e16ea59..acfeabd5 100644 --- a/src/Cedar/Sam.c +++ b/src/Cedar/Sam.c @@ -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) { diff --git a/src/Cedar/Server.c b/src/Cedar/Server.c index 241fd620..a7798768 100644 --- a/src/Cedar/Server.c +++ b/src/Cedar/Server.c @@ -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) { diff --git a/src/CurrentBuild.txt b/src/CurrentBuild.txt index 7e41b871..a52360ab 100644 --- a/src/CurrentBuild.txt +++ b/src/CurrentBuild.txt @@ -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 diff --git a/src/Mayaqua/Encrypt.c b/src/Mayaqua/Encrypt.c index d4641449..86fde1c2 100644 --- a/src/Mayaqua/Encrypt.c +++ b/src/Mayaqua/Encrypt.c @@ -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) { diff --git a/src/Mayaqua/Encrypt.h b/src/Mayaqua/Encrypt.h index 94b46f49..587b96d2 100644 --- a/src/Mayaqua/Encrypt.h +++ b/src/Mayaqua/Encrypt.h @@ -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); diff --git a/src/Mayaqua/Internat.c b/src/Mayaqua/Internat.c index 28f95f4b..59c51dc6 100644 --- a/src/Mayaqua/Internat.c +++ b/src/Mayaqua/Internat.c @@ -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; } } diff --git a/src/bin/hamcore/openvpn_sample.ovpn b/src/bin/hamcore/openvpn_sample.ovpn index 9a35e8c0..f52d015d 100644 --- a/src/bin/hamcore/openvpn_sample.ovpn +++ b/src/bin/hamcore/openvpn_sample.ovpn @@ -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 diff --git a/src/bin/hamcore/strtable_cn.stb b/src/bin/hamcore/strtable_cn.stb index 47d51945..2da89dcd 100644 --- a/src/bin/hamcore/strtable_cn.stb +++ b/src/bin/hamcore/strtable_cn.stb @@ -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 版上有效。 diff --git a/src/bin/hamcore/strtable_en.stb b/src/bin/hamcore/strtable_en.stb index c203c468..b28e458b 100644 --- a/src/bin/hamcore/strtable_en.stb +++ b/src/bin/hamcore/strtable_en.stb @@ -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. diff --git a/src/bin/hamcore/strtable_ja.stb b/src/bin/hamcore/strtable_ja.stb index 3b769319..d6ab9e8a 100644 --- a/src/bin/hamcore/strtable_ja.stb +++ b/src/bin/hamcore/strtable_ja.stb @@ -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 でのみ有効です。 diff --git a/src/bin/vpnweb.cab b/src/bin/vpnweb.cab index 1ee2d138..4e96fb6a 100644 Binary files a/src/bin/vpnweb.cab and b/src/bin/vpnweb.cab differ diff --git a/src/bin/vpnweb.ocx b/src/bin/vpnweb.ocx index f9f9e440..6d5d3cfc 100644 Binary files a/src/bin/vpnweb.ocx and b/src/bin/vpnweb.ocx differ diff --git a/src/makefiles/freebsd_32bit.mak b/src/makefiles/freebsd_32bit.mak index d39a9559..d1d73828 100644 --- a/src/makefiles/freebsd_32bit.mak +++ b/src/makefiles/freebsd_32bit.mak @@ -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/ diff --git a/src/makefiles/freebsd_32bit_nobits.mak b/src/makefiles/freebsd_32bit_nobits.mak index d39a9559..d1d73828 100644 --- a/src/makefiles/freebsd_32bit_nobits.mak +++ b/src/makefiles/freebsd_32bit_nobits.mak @@ -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/ diff --git a/src/makefiles/freebsd_64bit.mak b/src/makefiles/freebsd_64bit.mak index cbe69b33..92254974 100644 --- a/src/makefiles/freebsd_64bit.mak +++ b/src/makefiles/freebsd_64bit.mak @@ -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/ diff --git a/src/makefiles/freebsd_64bit_nobits.mak b/src/makefiles/freebsd_64bit_nobits.mak index cab2d5f2..73a60c39 100644 --- a/src/makefiles/freebsd_64bit_nobits.mak +++ b/src/makefiles/freebsd_64bit_nobits.mak @@ -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/ diff --git a/src/makefiles/linux_32bit.mak b/src/makefiles/linux_32bit.mak index 813f0216..55f71fdd 100644 --- a/src/makefiles/linux_32bit.mak +++ b/src/makefiles/linux_32bit.mak @@ -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/ diff --git a/src/makefiles/linux_32bit_nobits.mak b/src/makefiles/linux_32bit_nobits.mak index 813f0216..55f71fdd 100644 --- a/src/makefiles/linux_32bit_nobits.mak +++ b/src/makefiles/linux_32bit_nobits.mak @@ -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/ diff --git a/src/makefiles/linux_64bit.mak b/src/makefiles/linux_64bit.mak index f412087b..054d92ca 100644 --- a/src/makefiles/linux_64bit.mak +++ b/src/makefiles/linux_64bit.mak @@ -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/ diff --git a/src/makefiles/linux_64bit_nobits.mak b/src/makefiles/linux_64bit_nobits.mak index b810ca2e..da875941 100644 --- a/src/makefiles/linux_64bit_nobits.mak +++ b/src/makefiles/linux_64bit_nobits.mak @@ -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/ diff --git a/src/makefiles/macos_32bit.mak b/src/makefiles/macos_32bit.mak index bcd62eaa..16c84f00 100644 --- a/src/makefiles/macos_32bit.mak +++ b/src/makefiles/macos_32bit.mak @@ -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/ diff --git a/src/makefiles/macos_32bit_nobits.mak b/src/makefiles/macos_32bit_nobits.mak index bcd62eaa..16c84f00 100644 --- a/src/makefiles/macos_32bit_nobits.mak +++ b/src/makefiles/macos_32bit_nobits.mak @@ -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/ diff --git a/src/makefiles/macos_64bit.mak b/src/makefiles/macos_64bit.mak index 4bb11eb1..eea1122b 100644 --- a/src/makefiles/macos_64bit.mak +++ b/src/makefiles/macos_64bit.mak @@ -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/ diff --git a/src/makefiles/macos_64bit_nobits.mak b/src/makefiles/macos_64bit_nobits.mak index 063cd10d..16e91c4f 100644 --- a/src/makefiles/macos_64bit_nobits.mak +++ b/src/makefiles/macos_64bit_nobits.mak @@ -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/ diff --git a/src/makefiles/openbsd_32bit.mak b/src/makefiles/openbsd_32bit.mak index 40602ea2..0f8d062e 100644 --- a/src/makefiles/openbsd_32bit.mak +++ b/src/makefiles/openbsd_32bit.mak @@ -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/ diff --git a/src/makefiles/openbsd_32bit_nobits.mak b/src/makefiles/openbsd_32bit_nobits.mak index 40602ea2..0f8d062e 100644 --- a/src/makefiles/openbsd_32bit_nobits.mak +++ b/src/makefiles/openbsd_32bit_nobits.mak @@ -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/ diff --git a/src/makefiles/openbsd_64bit.mak b/src/makefiles/openbsd_64bit.mak index 6163ea1a..6f480fad 100644 --- a/src/makefiles/openbsd_64bit.mak +++ b/src/makefiles/openbsd_64bit.mak @@ -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/ diff --git a/src/makefiles/openbsd_64bit_nobits.mak b/src/makefiles/openbsd_64bit_nobits.mak index 56ee437a..0df8c4ca 100644 --- a/src/makefiles/openbsd_64bit_nobits.mak +++ b/src/makefiles/openbsd_64bit_nobits.mak @@ -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/ diff --git a/src/makefiles/solaris_32bit.mak b/src/makefiles/solaris_32bit.mak index 9cf3f68d..148e7484 100644 --- a/src/makefiles/solaris_32bit.mak +++ b/src/makefiles/solaris_32bit.mak @@ -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/ diff --git a/src/makefiles/solaris_32bit_nobits.mak b/src/makefiles/solaris_32bit_nobits.mak index 9cf3f68d..148e7484 100644 --- a/src/makefiles/solaris_32bit_nobits.mak +++ b/src/makefiles/solaris_32bit_nobits.mak @@ -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/ diff --git a/src/makefiles/solaris_64bit.mak b/src/makefiles/solaris_64bit.mak index 99560c79..30c40f22 100644 --- a/src/makefiles/solaris_64bit.mak +++ b/src/makefiles/solaris_64bit.mak @@ -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/ diff --git a/src/makefiles/solaris_64bit_nobits.mak b/src/makefiles/solaris_64bit_nobits.mak index e5a93b57..b5b320a1 100644 --- a/src/makefiles/solaris_64bit_nobits.mak +++ b/src/makefiles/solaris_64bit_nobits.mak @@ -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/ diff --git a/src/vpnweb/vpnweb.h b/src/vpnweb/vpnweb.h index db2382ff..ed9764fe 100644 --- a/src/vpnweb/vpnweb.h +++ b/src/vpnweb/vpnweb.h @@ -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) diff --git a/src/vpnweb/vpnweb_i.c b/src/vpnweb/vpnweb_i.c index 795c296b..0cf58a79 100644 --- a/src/vpnweb/vpnweb_i.c +++ b/src/vpnweb/vpnweb_i.c @@ -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) diff --git a/src/vpnweb/vpnweb_p.c b/src/vpnweb/vpnweb_p.c index f85e9f4a..04744e90 100644 --- a/src/vpnweb/vpnweb_p.c +++ b/src/vpnweb/vpnweb_p.c @@ -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)