Compare commits

...

31 Commits

Author SHA1 Message Date
geos_one
f945c945a0 add gcc 14 patches 2025-08-08 14:21:29 +02:00
geos_one
9188d6465e Update upstream source from tag 'upstream/4.44-9807'
Update to upstream version '4.44-9807'
with Debian dir a922a50ac1abb7cf732b395b029eb6ee05d403df
2025-08-08 12:20:09 +02:00
geos_one
b1e9cf955b New upstream version 4.44-9807 2025-08-08 12:19:10 +02:00
geos_one
682c6d6d08 Bump 2025-08-08 12:15:03 +02:00
geos_one
43fc056a50 Update upstream source from tag 'upstream/4.44-9807-rtm'
Update to upstream version '4.44-9807-rtm'
with Debian dir 91d6ab76ae01f266a56b5171b8e31c5cab0b803d
2025-08-08 12:10:49 +02:00
geos_one
a61de2e827 New upstream version 4.44-9807-rtm 2025-08-08 12:09:48 +02:00
Mario Fetka
8bf7619e83 Bump 2019-08-06 17:48:33 +02:00
Mario Fetka
78395fff92 Merge tag 'upstream/4.29.9680'
Upstream version 4.29.9680
2019-08-06 17:46:22 +02:00
Mario Fetka
e2164b858b Merge tag 'upstream/4.29.9680-rtm'
Upstream version 4.29.9680-rtm
2019-08-06 17:43:57 +02:00
Mario Fetka
36905fcc27 use latest ssl 2018-03-13 18:56:46 +01:00
Mario Fetka
5d515b03b2 Bump 2018-03-13 18:43:23 +01:00
Mario Fetka
11a71728dc readd updated ssl patch from freebsd 2018-03-13 18:35:29 +01:00
Mario Fetka
4eaa335ea3 readd updated ssl patch from freebsd 2018-03-13 18:31:59 +01:00
Mario Fetka
2c2919e3d6 add missing lib 2018-03-13 17:51:41 +01:00
Mario Fetka
d3a1dd7864 Merge tag 'upstream/4.25.9656'
Upstream version 4.25.9656
2018-03-13 17:42:59 +01:00
Mario Fetka
57631fc661 Merge tag 'upstream/4.25.9656-rtm'
Upstream version 4.25.9656-rtm
2018-03-13 17:33:01 +01:00
Mario Fetka
07de817ab3 Bump 2018-03-13 17:30:43 +01:00
Mario Fetka
4a107b38aa Merge tag 'upstream/4.25.9656-rtm'
Upstream version 4.25.9656-rtm
2018-03-13 17:27:27 +01:00
Mario Fetka
265a6a062c Bump 2018-03-13 17:17:28 +01:00
Mario Fetka
135c129931 Bump 2018-03-13 17:16:16 +01:00
Mario Fetka
39a01e0bb6 Merge tag 'upstream/4.25.9656-rtm'
Upstream version 4.25.9656-rtm
2018-03-13 17:12:23 +01:00
Mario Fetka
8be15c5e83 activate patch via dh quilt 2017-04-19 13:11:38 +02:00
Mario Fetka
1e1546aa10 activate patch via dh quilt 2017-04-19 13:10:54 +02:00
Mario Fetka
ed0ee04dc2 activate patch via dh quilt 2017-04-19 12:28:43 +02:00
Mario Fetka
ae45875dc6 update patch to rtm relase 2017-04-19 12:21:17 +02:00
Mario Fetka
9d14f83fa4 use quilt for patching 2017-04-19 12:12:51 +02:00
Mario Fetka
1fc2c0ee08 disable sslv3 2017-04-19 11:31:30 +02:00
Mario Fetka
bd943701e8 on stretch also the deep on libz ist needed 2017-04-19 10:49:54 +02:00
Mario Fetka
ca17e9314a on stretch use openssl 1.0 2017-04-19 10:38:43 +02:00
Mario Fetka
9aa5dc3871 Merge tag 'upstream/4.20.9608'
Upstream version 4.20.9608
2016-07-12 13:45:55 +02:00
Mario Fetka
e2304ce307 Bump 2016-07-12 13:35:23 +02:00
352 changed files with 99734 additions and 25624 deletions

@ -20,7 +20,7 @@ Protocol (SE-VPN Protocol)" . SE-VPN protocol encapsulates any Ethernet
packets into a HTTPS (HTTP over SSL) connection. Therefore SE-VPN protocol can packets into a HTTPS (HTTP over SSL) connection. Therefore SE-VPN protocol can
communicate beyond firewalls even if the firewall is configured to block communicate beyond firewalls even if the firewall is configured to block
traditional VPN packets by network administrator. SE-VPN protocol is designed traditional VPN packets by network administrator. SE-VPN protocol is designed
and implemented to comply TLS 1.0 (RFC 5246) and HTTPS (RFC 2818). However, it and implemented to comply TLS (RFC 5246) and HTTPS (RFC 2818). However, it
sometimes have different behavior to RFCs. If you are a network administrator sometimes have different behavior to RFCs. If you are a network administrator
and want to block SE-VPN protocols on the firewall, you can adopt a and want to block SE-VPN protocols on the firewall, you can adopt a
"white-list" policy on the firewall to filter any TCP or UDP packets on the "white-list" policy on the firewall to filter any TCP or UDP packets on the
@ -104,6 +104,25 @@ be disabled anytime by setting up so on the VPN-client side.
2. VPN Software 2. VPN Software
The notes in this section are not specific to SoftEther VPN or VPN Gate, but
apply to general system software. SoftEther VPN Client, SoftEther VPN Server,
SoftEther VPN Bridge, and VPN Gate Relay Service will be installed on your
computer as system services. System services always run in the background.
System services usually do not appear on the computer display. Then your
computer system is booted, system services automatically start in the
background even before you or other users log in. To check whether
PacketiX-related system service is running, check the process list or the
background service list of your OS (called as "Services" in Windows, or
"Daemons" in UNIX.) You can activate, deactivate, start, or stop system
services using the functions of the OS anytime. PacketiX-related GUI tools for
managing system services communicate with these system services. After you
terminate these management GUI tools, PacketiX-related system services will
continue to run in the background. System services consume CPU time, computer
power, memory and disk space. Because system services consume power, your
electricity charges and amount of thermal of your computer increase as result.
In addition, there is a possibility that the mechanical parts of the life of
your computer is reduced.
2.1. SoftEther VPN Client 2.1. SoftEther VPN Client
If you use SoftEther VPN Client on Windows, the Virtual Network Adapter device If you use SoftEther VPN Client on Windows, the Virtual Network Adapter device
driver will be installed on Windows. The Virtual Network Adapter is driver will be installed on Windows. The Virtual Network Adapter is
@ -356,10 +375,11 @@ Experiment Service Directory Server. The information includes the operator's
information which described in section 5.5, logging settings, uptime, information which described in section 5.5, logging settings, uptime,
operating system version, type of protocol, port numbers, quality information, operating system version, type of protocol, port numbers, quality information,
statistical information, VPN Gate clients' log history data (includes dates, statistical information, VPN Gate clients' log history data (includes dates,
IP addresses, version numbers and IDs) and the version of the software. These IP addresses, version numbers and IDs), log records of destination HTTP/HTTPS
information will be exposed on the directory. VPN Gate Service also receives a hostnames or IP addresses and port numbers of VPN Gate communications, and the
key for encoding which is described on the chapter 5.9 from the directory version of the software. These information may be exposed on the directory.
server. VPN Gate Service also receives a key for encoding which is described on the
chapter 5.9 from the directory server.
5.3. Details of VPN Gate Service's Behavior 5.3. Details of VPN Gate Service's Behavior
If you enable VPN Gate Service manually, which is disabled by default, the If you enable VPN Gate Service manually, which is disabled by default, the
@ -378,10 +398,13 @@ identify that the source of the communication has initiated from the VPN Gate
Service's hosting computer's IP address. However, for safety, any packets Service's hosting computer's IP address. However, for safety, any packets
which destinations are within 192.168.0.0/255.255.0.0, 172.16.0.0/255.240.0.0 which destinations are within 192.168.0.0/255.255.0.0, 172.16.0.0/255.240.0.0
or 10.0.0.0/255.0.0.0 will be blocked by the "VPNGATE" Virtual Hub in order to or 10.0.0.0/255.0.0.0 will be blocked by the "VPNGATE" Virtual Hub in order to
protect your local network. Therefore, if you run VPN Gate Service on your protect your local network. Any packets which destinations are within
corporate network or private network, it is safe because anonymous VPN Client 169.254.0.0/16, 224.0.0.0/4 or 100.64.0.0/10 will also be blocked for just in
users will not be permitted to access such private networks. VPN Gate Service case. These packet filters except DNS, ICMP and ARP packets. Therefore, if you
also serves as relay for accessing to the VPN Gate Directory Server. run VPN Gate Service on your corporate network or private network, it is safe
because anonymous VPN Client users will not be permitted to access such
private networks. VPN Gate Service also serves as relay for accessing to the
VPN Gate Directory Server.
In order to make VPN Gate Service familiar with firewalls and NATs, it opens In order to make VPN Gate Service familiar with firewalls and NATs, it opens
an UDP port by using the NAT Traversal function which is described on the an UDP port by using the NAT Traversal function which is described on the
section 1.2. It also opens and listens on some TCP ports, and some TCP and UDP section 1.2. It also opens and listens on some TCP ports, and some TCP and UDP
@ -471,6 +494,8 @@ of Tsukuba, Japan. You can find the contact address at
http://www.vpngate.net/. The administrator of VPN Gate Service will respond to http://www.vpngate.net/. The administrator of VPN Gate Service will respond to
decode the packet logs if there is an appropriate and legal request from court decode the packet logs if there is an appropriate and legal request from court
or other judicial authorities, according to laws. or other judicial authorities, according to laws.
The Packet Logs Automatic Archiving and Encoding Function may be disabled
according to technical or administrative reason.
5.10. Caution if You Operate VPN Gate Service in the Japan's Territories 5.10. Caution if You Operate VPN Gate Service in the Japan's Territories
When a user operates VPN Gate Service in the Japan's territories, such an act When a user operates VPN Gate Service in the Japan's territories, such an act
@ -480,10 +505,7 @@ a subject to the law. However, in such a circumstance, according to the
non- profitable operations of communications are not identified as a non- profitable operations of communications are not identified as a
"telecommunication business" . So usual operators of VPN Gate Service are not "telecommunication business" . So usual operators of VPN Gate Service are not
subjects to "telecommunication business operators" , and not be mandated to subjects to "telecommunication business operators" , and not be mandated to
register to the government. Even so, legalities to protect the privacy of register to the government.
communication still imposed. As a conclusion, if you operate VPN Gate Service
in the Japan's Territories, you must not leak the secrets of communications
which are transmitted via your operating VPN Gate Service.
5.11. VPN Gate Client 5.11. VPN Gate Client
If SoftEther VPN Client contains the VPN Gate Client plug-in, you can use it If SoftEther VPN Client contains the VPN Gate Client plug-in, you can use it
@ -563,3 +585,41 @@ functions. Therefore, in such a case, you must disable the P2P Relay Function
on the VPN Gate Client manually by setting the "DisableRelayServer" flag if on the VPN Gate Client manually by setting the "DisableRelayServer" flag if
you reside in such a restricted area, in your own responsibility. you reside in such a restricted area, in your own responsibility.
SoftEther VPN and VPN Gate (where applicable) are provided, distributed and
operated under the responsibility of SoftEther Corporation (Corporate Number:
1050001016519, Tsukuba, Ibaraki, Japan). These projects were researched and
developed in collaboration with Tsukuba University, a national university in
Japan.
THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER
JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH,
DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY
JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS,
AGAINST US (SOFTETHER CORPORATION OR OTHER SUPPLIERS), OR ANY JURIDICAL
DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING, MODIFYING,
MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR SELLING COPIES OF THIS
SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND CONTROLLED BY JAPANESE LAWS,
AND YOU MUST FURTHER CONSENT TO EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS
SITTING IN TOKYO, JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL
JURISDICTION AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY
IN THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
SUPPLIERS, PROVIDERS, OPERATORS, AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
IMPORTANT NOTE: USE OF THIS SOFTWARE AND SERVICE BY INDIVIDUALS TO WHOM THE
CONSUMER CONTRACT ACT APPLIES IS NOT ALLOWED. THIS SOFTWARE IS INTENDED FOR
PROFESSIONALS AND IS NOT DESIGNED FOR PURELY BUSINESS-UNRELATED CONSUMERS.
THIS SOFTWARE AND SERVICE MAY BE USED ONLY FOR BUSINESS, COMMERCIAL,
NON-PROFIT, ORGANIZATIONAL OPERATIONS, RESEARCH AND DEVELOPMENT PURPOSES OR
OTHER NON-CONSUMPTIVE PURPOSES. THIS SOFTWARE IS NOT INTENDED FOR USE BY
CONSUMERS. THIS SOFTWARE MAY NOT BE USED BY ANY INDIVIDUAL TO WHOM THE
CONSUMER RIGHTS PROTECTIONS IN THE CONSUMER CONTRACT ACT OF JAPAN OR
EQUIVALENT LAWS OF OTHER COUNTRIES APPLY. IF AN INDIVIDUAL USES THE SOFTWARE,
THE USE OF THE SOFTWARE SHALL BE DEEMED TO BE FOR BUSINESS PURPOSES.

9
configure vendored

@ -74,6 +74,13 @@ OpenBSD)
;; ;;
esac esac
NOBITS=""
case "`uname -m`" in
aarch*|arm*|arm*)
NOBITS="_nobits"
;;
esac
CPU="" CPU=""
case "`uname -m`" in case "`uname -m`" in
x86_64|amd64|aarch64|arm64|armv8*|mips64|ppc64|sparc64|alpha|ia64) x86_64|amd64|aarch64|arm64|armv8*|mips64|ppc64|sparc64|alpha|ia64)
@ -107,6 +114,6 @@ i?86|x86pc|i86pc|armv4*|armv5*|armv6*|armv7*)
;; ;;
esac esac
cp src/makefiles/${OS}_${CPU}.mak Makefile cp src/makefiles/${OS}_${CPU}${NOBITS}.mak Makefile
echo "The Makefile is generated. Run 'make' to build SoftEther VPN." echo "The Makefile is generated. Run 'make' to build SoftEther VPN."

10
debian/changelog vendored

@ -1,3 +1,13 @@
softether-vpn (4.44-9807-rtm) unstable; urgency=medium
[ Mario Fetka ]
* Bump
[ geos_one ]
* New upstream version 4.44-9807-rtm
-- root <mario.fetka@disconnected-by-peer.at> Fri, 08 Aug 2025 12:14:30 +0200
softether-vpn (0:4.04.9412-rtm) unstable; urgency=low softether-vpn (0:4.04.9412-rtm) unstable; urgency=low
* Testing debianization * Testing debianization

2
debian/control vendored

@ -2,7 +2,7 @@ Source: softether-vpn
Section: net Section: net
Priority: optional Priority: optional
Maintainer: Dmitry Orlov <me@mosquito.su> Maintainer: Dmitry Orlov <me@mosquito.su>
Build-Depends: debhelper (>= 7.0.50~), libncurses-dev, linux-libc-dev, libssl-dev, libreadline-dev, build-essential, dh-exec Build-Depends: debhelper (>= 7.0.50~), libncurses-dev, linux-libc-dev, libssl-dev , libreadline-dev, build-essential, dh-exec, zlib1g-dev
Standards-Version: 3.9.1 Standards-Version: 3.9.1
Homepage: http://www.softether.org/ Homepage: http://www.softether.org/

@ -0,0 +1,54 @@
From 1199ecd57dffdbc65c47baa61c4e836df5700244 Mon Sep 17 00:00:00 2001
From: NiteHawk <n1tehawk@users.noreply.github.com>
Date: Sun, 20 Jul 2025 18:31:49 +0200
Subject: [PATCH] [followup] Fix some oversights in previous commit
---
src/Mayaqua/Secure.c | 4 ++--
src/Mayaqua/Secure.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/Mayaqua/Secure.c b/src/Mayaqua/Secure.c
index 7132f92a..da62f983 100644
--- a/src/Mayaqua/Secure.c
+++ b/src/Mayaqua/Secure.c
@@ -1710,7 +1710,7 @@ void CloseSecSession(SECURE *sec)
}
// Open the session
-bool OpenSecSession(SECURE *sec, UINT slot_number)
+bool OpenSecSession(SECURE *sec, CK_SLOT_ID slot_number)
{
UINT err = 0;
CK_SESSION_HANDLE session;
@@ -1835,7 +1835,7 @@ SECURE *OpenSec(UINT id)
return NULL;
}
- sec->SlotIdList = (CK_SLOT_ID *)ZeroMalloc(sizeof(UINT) * sec->NumSlot);
+ sec->SlotIdList = (CK_SLOT_ID *)ZeroMalloc(sizeof(CK_SLOT_ID) * sec->NumSlot);
if (sec->Api->C_GetSlotList(TRUE, sec->SlotIdList, &sec->NumSlot) != CKR_OK)
{
diff --git a/src/Mayaqua/Secure.h b/src/Mayaqua/Secure.h
index 649a8989..5cf574a4 100644
--- a/src/Mayaqua/Secure.h
+++ b/src/Mayaqua/Secure.h
@@ -162,7 +162,7 @@ struct SECURE
CK_SLOT_ID *SlotIdList; // Slot ID list
bool SessionCreated; // Session creation flags
UINT SessionId; // Session ID
- UINT SessionSlotNumber; // Slot ID of the session
+ CK_SLOT_ID SessionSlotNumber; // Slot ID of the session
bool LoginFlag; // Logged-in flag
SEC_INFO *Info; // Token information
LIST *EnumCache; // Enumeration cache
@@ -220,7 +220,7 @@ bool CheckSecureDeviceId(UINT id);
SECURE_DEVICE *GetSecureDevice(UINT id);
SECURE *OpenSec(UINT id);
void CloseSec(SECURE *sec);
-bool OpenSecSession(SECURE *sec, UINT slot_number);
+bool OpenSecSession(SECURE *sec, CK_SLOT_ID slot_number);
void CloseSecSession(SECURE *sec);
bool LoginSec(SECURE *sec, char *pin);
void LogoutSec(SECURE *sec);

@ -0,0 +1,190 @@
From c6a357e29e93c1c3a0952c97adbb82dcb8a9c1f9 Mon Sep 17 00:00:00 2001
From: NiteHawk <n1tehawk@users.noreply.github.com>
Date: Sun, 20 Jul 2025 17:54:33 +0200
Subject: [PATCH] Fix Unix compilation when using GCC 14.x
GCC 14 defaults to stricter type checking, causing compilation errors that
result in a build failure with the current source code (v4.44 9807 rtm).
This patch addresses these to get the (Unix) build working again.
Tested with gcc 14.3.0 on Gentoo Linux.
---
src/Cedar/Console.c | 16 +++++++++-------
src/Cedar/VLanUnix.h | 1 +
src/Mayaqua/Secure.c | 18 +++++++++---------
src/Mayaqua/Secure.h | 7 ++++---
src/Mayaqua/Unix.c | 3 +--
5 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/src/Cedar/Console.c b/src/Cedar/Console.c
index 3c6c90c20..bfb9bd524 100644
--- a/src/Cedar/Console.c
+++ b/src/Cedar/Console.c
@@ -1981,6 +1981,14 @@ char *ParseCommandA(wchar_t *str, char *name)
return ret;
}
+#ifndef OS_WIN32
+ // use a simple wrapper to create a compatible function,
+ // allowing for uniform use of getch() below
+ static int getch(void) {
+ return getc(stdin);
+ }
+#endif // OS_WIN32
+
// Password prompt
bool PasswordPrompt(char *password, UINT size)
{
@@ -2005,13 +2013,7 @@ bool PasswordPrompt(char *password, UINT size)
while (true)
{
- int c;
-
-#ifdef OS_WIN32
- c = getch();
-#else // OS_WIN32
- c = getc(stdin);
-#endif // OS_WIN32
+ int c = getch();
if (c >= 0x20 && c <= 0x7E)
{
diff --git a/src/Cedar/VLanUnix.h b/src/Cedar/VLanUnix.h
index fa878e599..556aecda6 100644
--- a/src/Cedar/VLanUnix.h
+++ b/src/Cedar/VLanUnix.h
@@ -122,6 +122,7 @@ struct VLAN
VLAN *NewVLan(char *instance_name, VLAN_PARAM *param);
VLAN *NewTap(char *name, char *mac_address);
void FreeVLan(VLAN *v);
+void FreeTap(VLAN *v);
CANCEL *VLanGetCancel(VLAN *v);
bool VLanGetNextPacket(VLAN *v, void **buf, UINT *size);
bool VLanPutPacket(VLAN *v, void *buf, UINT size);
diff --git a/src/Mayaqua/Secure.c b/src/Mayaqua/Secure.c
index 17cc2717f..7132f92a3 100644
--- a/src/Mayaqua/Secure.c
+++ b/src/Mayaqua/Secure.c
@@ -370,7 +370,7 @@ bool SignSec(SECURE *sec, char *name, void *dst, void *src, UINT size)
}
// Sign with the private key of the secure device
-bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, UINT size)
+bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, CK_ULONG size)
{
CK_MECHANISM mechanism = {CKM_RSA_PKCS, NULL, 0};
UINT ret;
@@ -474,7 +474,7 @@ bool WriteSecKey(SECURE *sec, bool private_obj, char *name, K *k)
UINT key_type = CKK_RSA;
CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
UINT obj_class = CKO_PRIVATE_KEY;
- UINT object;
+ CK_OBJECT_HANDLE object;
UINT ret;
BUF *b;
RSA *rsa;
@@ -716,7 +716,7 @@ bool WriteSecCert(SECURE *sec, bool private_obj, char *name, X *x)
UCHAR value[4096];
UINT ret;
BUF *b;
- UINT object;
+ CK_OBJECT_HANDLE object;
CK_ATTRIBUTE a[] =
{
{CKA_SUBJECT, subject, 0}, // 0
@@ -1264,8 +1264,8 @@ LIST *CloneEnumSecObject(LIST *o)
LIST *EnumSecObject(SECURE *sec)
{
CK_BBOOL b_true = true, b_false = false;
- UINT objects[MAX_OBJ];
- UINT i;
+ CK_OBJECT_HANDLE objects[MAX_OBJ];
+ CK_ULONG i;
UINT ret;
LIST *o;
CK_ATTRIBUTE dummy[1];
@@ -1273,7 +1273,7 @@ LIST *EnumSecObject(SECURE *sec)
{
{CKA_TOKEN, &b_true, sizeof(b_true)},
};
- UINT num_objects = MAX_OBJ;
+ CK_ULONG num_objects = MAX_OBJ;
// Validate arguments
if (sec == NULL)
{
@@ -1389,7 +1389,7 @@ bool WriteSecData(SECURE *sec, bool private_obj, char *name, void *data, UINT si
{
UINT object_class = CKO_DATA;
CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
- UINT object;
+ CK_OBJECT_HANDLE object;
CK_ATTRIBUTE a[] =
{
{CKA_TOKEN, &b_true, sizeof(b_true)},
@@ -1713,7 +1713,7 @@ void CloseSecSession(SECURE *sec)
bool OpenSecSession(SECURE *sec, UINT slot_number)
{
UINT err = 0;
- UINT session;
+ CK_SESSION_HANDLE session;
// Validate arguments
if (sec == NULL)
{
@@ -1835,7 +1835,7 @@ SECURE *OpenSec(UINT id)
return NULL;
}
- sec->SlotIdList = (UINT *)ZeroMalloc(sizeof(UINT) * sec->NumSlot);
+ sec->SlotIdList = (CK_SLOT_ID *)ZeroMalloc(sizeof(UINT) * sec->NumSlot);
if (sec->Api->C_GetSlotList(TRUE, sec->SlotIdList, &sec->NumSlot) != CKR_OK)
{
diff --git a/src/Mayaqua/Secure.h b/src/Mayaqua/Secure.h
index 7654acbf5..649a89894 100644
--- a/src/Mayaqua/Secure.h
+++ b/src/Mayaqua/Secure.h
@@ -109,6 +109,7 @@
#define MAX_SEC_DATA_SIZE 4096
// Type declaration related to PKCS#11
+#include "cryptoki.h"
#ifndef SECURE_C
typedef struct CK_FUNCTION_LIST *CK_FUNCTION_LIST_PTR;
typedef struct SEC_DATA_WIN32 SEC_DATA_WIN32;
@@ -157,8 +158,8 @@ struct SECURE
UINT Error; // The error that last occurred
struct CK_FUNCTION_LIST *Api; // API
bool Initialized; // Initialization flag
- UINT NumSlot; // The number of slots
- UINT *SlotIdList; // Slot ID list
+ CK_ULONG NumSlot; // The number of slots
+ CK_SLOT_ID *SlotIdList; // Slot ID list
bool SessionCreated; // Session creation flags
UINT SessionId; // Session ID
UINT SessionSlotNumber; // Slot ID of the session
@@ -247,7 +248,7 @@ X *ReadSecCertFromObject(SECURE *sec, SEC_OBJ *obj);
X *ReadSecCert(SECURE *sec, char *name);
bool WriteSecKey(SECURE *sec, bool private_obj, char *name, K *k);
bool DeleteSecKey(SECURE *sec, char *name);
-bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, UINT size);
+bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, CK_ULONG size);
bool SignSec(SECURE *sec, char *name, void *dst, void *src, UINT size);
bool ChangePin(SECURE *sec, char *old_pin, char *new_pin);
void TestSec();
diff --git a/src/Mayaqua/Unix.c b/src/Mayaqua/Unix.c
index c988ea268..b7b4b9150 100644
--- a/src/Mayaqua/Unix.c
+++ b/src/Mayaqua/Unix.c
@@ -309,9 +309,8 @@ OS_DISPATCH_TABLE *UnixGetDispatchTable()
return &t;
}
-static void *signal_received_for_ignore(int sig, siginfo_t *info, void *ucontext)
+static void signal_received_for_ignore(int sig, siginfo_t *info, void *ucontext)
{
- return NULL;
}
// Ignore the signal flew to the thread

2
debian/patches/series vendored Normal file

@ -0,0 +1,2 @@
c6a357e29e93c1c3a0952c97adbb82dcb8a9c1f9.patch
1199ecd57dffdbc65c47baa61c4e836df5700244.patch

1
debian/softether-vpnbridge.service vendored Symbolic link

@ -0,0 +1 @@
../systemd/softether-vpnbridge.service

1
debian/softether-vpnclient.service vendored Symbolic link

@ -0,0 +1 @@
../systemd/softether-vpnclient.service

1
debian/softether-vpnserver.service vendored Symbolic link

@ -0,0 +1 @@
../systemd/softether-vpnserver.service

@ -0,0 +1 @@
crosslib_win32_v3_230612_02

Binary file not shown.

@ -0,0 +1 @@
crosslib_win32_191020_02

Binary file not shown.

Binary file not shown.

@ -0,0 +1 @@
crosslib_win32_v2_220323_01

@ -1330,7 +1330,45 @@ namespace BuildUtil
int certid = vl["CERTID"].IntValue; int certid = vl["CERTID"].IntValue;
int shamode = vl["SHAMODE"].IntValue; int shamode = vl["SHAMODE"].IntValue;
CodeSign.SignFile(destFileName, srcFileName, comment, kernel, certid, shamode); CodeSign.SignFile(destFileName, srcFileName, comment, kernel, false, false);
return 0;
}
// Sign the file
[ConsoleCommandMethod(
"Sign files using Authenticode certificates.",
"SignCode2 [filename] [/DEST:destfilename] [/COMMENT:comment] [/KERNEL:yes|no] [/CERT:certname]",
"Sign files using Authenticode certificates.",
"[filename]:Specify the target filename.",
"DEST:Specify the destination filename. If this parameter is not specified, the target file will be overwritten.",
"COMMENT:Provide a description of the signed content.",
"KERNEL:Specify \"yes\" if Windows Vista / 7 Kernel Mode Driver Signing is needed."
)]
static int SignCode2(ConsoleService c, string cmdName, string str)
{
ConsoleParam[] args =
{
new ConsoleParam("[filename]", ConsoleService.Prompt, "Filename: ", ConsoleService.EvalNotEmpty, null),
new ConsoleParam("DEST"),
new ConsoleParam("COMMENT", ConsoleService.Prompt, "Comment: ", ConsoleService.EvalNotEmpty, null),
new ConsoleParam("KERNEL"),
new ConsoleParam("CERT"),
};
ConsoleParamValueList vl = c.ParseCommandList(cmdName, str, args);
string destFileName = vl["DEST"].StrValue;
string srcFileName = vl.DefaultParam.StrValue;
if (Str.IsEmptyStr(destFileName))
{
destFileName = srcFileName;
}
string comment = vl["COMMENT"].StrValue;
bool kernel = vl["KERNEL"].BoolValue;
string cert = vl["CERT"].StrValue;
CodeSign.SignFile2(destFileName, srcFileName, comment, kernel, cert);
return 0; return 0;
} }

@ -126,6 +126,52 @@ using BuildUtil.HvSignService;
namespace BuildUtil namespace BuildUtil
{ {
public static class SignClient
{
const string SeInternalPasswordFilePath = @"\\192.168.3.2\share\tmp\signserver\password.txt";
const string Url = "https://codesignserver:7006/sign";
public static byte[] Sign(byte[] srcData, string certName, string flags, string comment)
{
string password = File.ReadAllText(SeInternalPasswordFilePath);
string url = Url + "?password=" + password + "&cert=" + certName + "&flags=" + flags + "&comment=" + comment;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
WebRequest req = HttpWebRequest.Create(url);
req.Timeout = 60 * 1000;
req.Method = "POST";
using (Stream reqs = req.GetRequestStream())
{
reqs.Write(srcData, 0, srcData.Length);
reqs.Close();
WebResponse res = req.GetResponse();
using (Stream ress = res.GetResponseStream())
{
byte[] tmp = new byte[4 * 1024 * 1024];
MemoryStream ms = new MemoryStream();
while (true)
{
int r = ress.Read(tmp, 0, tmp.Length);
if (r <= 0) break;
ms.Write(tmp, 0, r);
}
return ms.ToArray();
}
}
}
}
public static class CodeSign public static class CodeSign
{ {
public const int NumRetries = 1; public const int NumRetries = 1;
@ -146,9 +192,13 @@ namespace BuildUtil
static object lockObj = new object(); static object lockObj = new object();
// Digital-sign the data on the memory // Digital-sign the data on the memory
public static byte[] SignMemory(byte[] srcData, string comment, bool kernelModeDriver, int cert_id, int sha_mode) public static byte[] SignMemory(byte[] srcData, string comment, bool kernelModeDriver, bool evCert, bool skipVerify)
{ {
#if !BU_OSS #if !BU_OSS
// 2020/01/19 switch to the new system
return SignClient.Sign(srcData, evCert ? "SoftEtherEv" : "SoftEtherFile", (kernelModeDriver ? "Driver" : "") + "," + (skipVerify ? "SkipVerify" : ""), comment);
/*
int i; int i;
string out_filename = null; string out_filename = null;
byte[] ret = null; byte[] ret = null;
@ -240,37 +290,47 @@ namespace BuildUtil
File.Delete(tmpFileName); File.Delete(tmpFileName);
} }
return ret; return ret;*/
#else // BU_OSS #else // BU_OSS
return srcData; return srcData;
#endif // BU_OSS #endif // BU_OSS
} }
// Digital-sign the data on the file // Digital-sign the data on the file
public static void SignFile(string destFileName, string srcFileName, string comment, bool kernelModeDriver) public static void SignFile2(string destFileName, string srcFileName, string comment, bool kernelModeDriver, string certName)
{
int cert_id = UsingCertId;
SignFile(destFileName, srcFileName, comment, kernelModeDriver, cert_id, 0);
}
public static void SignFile(string destFileName, string srcFileName, string comment, bool kernelModeDriver, int cert_id, int sha_mode)
{ {
#if !BU_OSS #if !BU_OSS
if (cert_id == 0)
{
cert_id = UsingCertId;
}
Con.WriteLine("Signing for '{0}'...", Path.GetFileName(destFileName)); Con.WriteLine("Signing for '{0}'...", Path.GetFileName(destFileName));
byte[] srcData = File.ReadAllBytes(srcFileName); byte[] srcData = File.ReadAllBytes(srcFileName);
if (srcFileName.EndsWith(".msi", StringComparison.InvariantCultureIgnoreCase)) byte[] destData = SignClient.Sign(srcData, certName, kernelModeDriver ? "Driver" : "", comment);
try
{
File.Delete(destFileName);
}
catch
{ {
sha_mode = 1;
// todo: Set 2 in future !!!
} }
byte[] destData = SignMemory(srcData, comment, kernelModeDriver, cert_id, sha_mode); File.WriteAllBytes(destFileName, destData);
Con.WriteLine("Done.");
#else // BU_OSS
Con.WriteLine("Skipping the code signing for '{0}' in the build process. You can insert your own authenticode sign process here.", srcFileName);
#endif // BU_OSS
}
// Digital-sign the data on the file
public static void SignFile(string destFileName, string srcFileName, string comment, bool kernelModeDriver, bool evCert, bool skipVerify)
{
#if !BU_OSS
Con.WriteLine("Signing for '{0}'...", Path.GetFileName(destFileName));
byte[] srcData = File.ReadAllBytes(srcFileName);
byte[] destData = SignMemory(srcData, comment, kernelModeDriver, evCert, skipVerify);
try try
{ {

@ -600,13 +600,6 @@ namespace BuildUtil
string gccOptionForLink; string gccOptionForLink;
string gccOptionForCompile; string gccOptionForCompile;
bool try_no_pie = false;
if (this.Os == OSList.Linux)
{
try_no_pie = true;
}
generateGccOptions(srcDir, false, false, out gccOptionForLink, out gccOptionForCompile); generateGccOptions(srcDir, false, false, out gccOptionForLink, out gccOptionForCompile);
string codeDir = Path.Combine(srcDir, "code"); string codeDir = Path.Combine(srcDir, "code");
@ -629,22 +622,8 @@ namespace BuildUtil
sr.WriteLine(); sr.WriteLine();
sr.WriteLine("CC={0}", this.Compiler); sr.WriteLine("CC={0}", this.Compiler);
sr.WriteLine(); sr.WriteLine();
if (try_no_pie)
{
sr.WriteLine("#For Ubuntu 18.04 or later we must add -no-pie option for gcc if supported");
sr.WriteLine("RET_NO_PIE_CHECK := $(shell $(CC) -no-pie 2>&1 | grep no-pie | wc -w)");
sr.WriteLine("ifeq ($(RET_NO_PIE_CHECK),0)");
sr.WriteLine("\tNO_PIE_OPTION=-no-pie");
sr.WriteLine("else");
sr.WriteLine("\tNO_PIE_OPTION=");
sr.WriteLine("endif");
}
else
{
sr.WriteLine("NO_PIE_OPTION=");
}
sr.WriteLine(); sr.WriteLine();
sr.WriteLine("OPTIONS=$(NO_PIE_OPTION) {0}", gccOptionForLink); sr.WriteLine("OPTIONS={0}", gccOptionForLink);
sr.WriteLine(); sr.WriteLine();
sr.WriteLine("default:"); sr.WriteLine("default:");
sr.WriteLine("\t@./.install.sh"); sr.WriteLine("\t@./.install.sh");
@ -653,7 +632,7 @@ namespace BuildUtil
sr.WriteLine("# You have to read and agree the license agreement at the same directory"); sr.WriteLine("# You have to read and agree the license agreement at the same directory");
sr.WriteLine("# before using this software."); sr.WriteLine("# before using this software.");
sr.WriteLine(); sr.WriteLine();
sr.WriteLine("i_read_and_agree_the_license_agreement:"); sr.WriteLine("main:");
sr.WriteLine("\t@echo \"Preparing {0}...\"", BuildHelper.GetSoftwareTitle(this.Software)); sr.WriteLine("\t@echo \"Preparing {0}...\"", BuildHelper.GetSoftwareTitle(this.Software));
@ -694,6 +673,9 @@ namespace BuildUtil
sr.WriteLine("\t@echo \"You can choose your prefered language of {0} at any time.\"", BuildHelper.GetSoftwareTitle(this.Software)); sr.WriteLine("\t@echo \"You can choose your prefered language of {0} at any time.\"", BuildHelper.GetSoftwareTitle(this.Software));
sr.WriteLine("\t@echo \"To switch the current language, open and edit the 'lang.config' file.\""); sr.WriteLine("\t@echo \"To switch the current language, open and edit the 'lang.config' file.\"");
sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo \"Note: the administrative password is not set on the VPN Server. Please set your own administrative password as soon as possible by vpncmd or the GUI manager.\"");
sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo");
@ -707,6 +689,7 @@ namespace BuildUtil
sr.WriteLine("\t@echo \"And please execute './vpncmd' to run the SoftEther VPN Command-Line Utility to configure {0}.\"", BuildHelper.GetSoftwareTitle(this.Software)); sr.WriteLine("\t@echo \"And please execute './vpncmd' to run the SoftEther VPN Command-Line Utility to configure {0}.\"", BuildHelper.GetSoftwareTitle(this.Software));
#endif #endif
sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo");
#if !BU_SOFTETHER #if !BU_SOFTETHER
sr.WriteLine("\t@echo \"Of course, you can use the VPN Server Manager GUI Application for Windows on the other Windows PC in order to configure the {0} remotely.\"", BuildHelper.GetSoftwareTitle(this.Software)); sr.WriteLine("\t@echo \"Of course, you can use the VPN Server Manager GUI Application for Windows on the other Windows PC in order to configure the {0} remotely.\"", BuildHelper.GetSoftwareTitle(this.Software));
#else #else
@ -715,7 +698,6 @@ namespace BuildUtil
#if !BU_SOFTETHER #if !BU_SOFTETHER
#else #else
sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo \"*** For Windows users ***\""); sr.WriteLine("\t@echo \"*** For Windows users ***\"");
sr.WriteLine("\t@echo \"You can download the SoftEther VPN Server Manager for Windows\""); sr.WriteLine("\t@echo \"You can download the SoftEther VPN Server Manager for Windows\"");
@ -730,6 +712,30 @@ namespace BuildUtil
sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo");
#endif #endif
sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo");
#if !BU_SOFTETHER
sr.WriteLine("\t@echo \"*** SoftEther VPN Server HTML5 Web Administration Console (NEW) ***\"");
#else
sr.WriteLine("\t@echo \"*** PacketiX VPN Server HTML5 Web Administration Console (NEW) ***\"");
#endif
sr.WriteLine("\t@echo \"This VPN Server / Bridge has the built-in HTML5 Web Administration Console.\"");
sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo \"After you start the server daemon, you can open the HTML5 Web Administration Console is available at\"");
sr.WriteLine("\t@echo");
#if !BU_SOFTETHER
sr.WriteLine("\t@echo \"https://127.0.0.1:8888/\"");
sr.WriteLine("\t@echo \" or\"");
sr.WriteLine("\t@echo \"https://ip_address_of_the_vpn_server:8888/\"");
#else
sr.WriteLine("\t@echo \"https://127.0.0.1:5555/\"");
sr.WriteLine("\t@echo \"or\"");
sr.WriteLine("\t@echo \"https://ip_address_of_the_vpn_server:5555/\"");
#endif
sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo \"This HTML5 page is obviously under construction, and your HTML5 development contribution is very appreciated.\"");
sr.WriteLine("\t@echo");
sr.WriteLine("\t@echo \"--------------------------------------------------------------------\""); sr.WriteLine("\t@echo \"--------------------------------------------------------------------\"");
sr.WriteLine("\t@echo"); sr.WriteLine("\t@echo");
@ -964,6 +970,9 @@ namespace BuildUtil
includes.Add("./Cedar/"); includes.Add("./Cedar/");
includes.Add("./Mayaqua/"); includes.Add("./Mayaqua/");
// Generate the PIE code by default
options.Add("-fPIE");
// Determine options // Determine options
if (debugMode) if (debugMode)
{ {
@ -1042,11 +1051,11 @@ namespace BuildUtil
options.Add("-lrt"); options.Add("-lrt");
options.Add("-lnsl"); options.Add("-lnsl");
options.Add("-lsocket"); options.Add("-lsocket");
options.Add("-ldl"); //options.Add("-ldl");
} }
else if (this.Os == OSList.Linux) else if (this.Os == OSList.Linux)
{ {
options.Add("-ldl"); //options.Add("-ldl");
options.Add("-lrt"); options.Add("-lrt");
} }
else if (this.Os == OSList.MacOS) else if (this.Os == OSList.MacOS)
@ -1068,6 +1077,12 @@ namespace BuildUtil
options.Add("-lpthread"); options.Add("-lpthread");
gccOptionForLink = MakeGccOptions(new string[0], new string[0], options.ToArray(), libs.ToArray()); gccOptionForLink = MakeGccOptions(new string[0], new string[0], options.ToArray(), libs.ToArray());
if (this.Os == OSList.Linux || this.Os == OSList.Solaris)
{
// Add the "-ldl" flag on the end of the command line
gccOptionForLink += " -ldl";
}
} }
public static string MakeGccOptions(string[] macros, string[] includeDirs, string[] options, string[] libs) public static string MakeGccOptions(string[] macros, string[] includeDirs, string[] options, string[] libs)

@ -552,6 +552,24 @@ namespace BuildUtil
} }
} }
// Delete node_modules file
public static void DeleteNodeModulesFilesFromHamCoreBuilder(HamCoreBuilder b)
{
List<string> removeFiles = new List<string>();
foreach (HamCoreBuilderFileEntry f in b.FileList)
{
string name = f.Name;
if (name.IndexOf(@"\node_modules\", StringComparison.InvariantCultureIgnoreCase) != -1)
{
removeFiles.Add(name);
}
}
foreach (string file in removeFiles)
{
b.DeleteFile(file);
}
}
// Build Hamcore file // Build Hamcore file
public static void BuildHamcore() public static void BuildHamcore()
{ {
@ -594,6 +612,7 @@ namespace BuildUtil
Con.WriteLine("* Building hamcore ..."); Con.WriteLine("* Building hamcore ...");
DeleteSVNFilesFromHamCoreBuilder(b); DeleteSVNFilesFromHamCoreBuilder(b);
DeleteNodeModulesFilesFromHamCoreBuilder(b);
try try
{ {
@ -619,6 +638,7 @@ namespace BuildUtil
} }
DeleteSVNFilesFromHamCoreBuilder(b); DeleteSVNFilesFromHamCoreBuilder(b);
DeleteNodeModulesFilesFromHamCoreBuilder(b);
try try
{ {

@ -163,7 +163,11 @@ namespace BuildUtil
null); null);
public static readonly BuildSoftware vpnserver_linux_armeabi_ja = public static readonly BuildSoftware vpnserver_linux_armeabi_ja =
new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.armeabi, OSList.Linux, new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.armeabi, OSList.Linux,
"linux-armeabi-32bit", false, "linux-armeabi-32bit-4.3.2", true, "linux-armeabi-32bit", false, "linux-armeabi-32bit-4.3.2", false,
null);
public static readonly BuildSoftware vpnserver_linux_arm64_ja =
new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.arm64, OSList.Linux,
"linux-arm64-64bit", false, "linux-arm64-64bit-4.8.4", false,
null); null);
public static readonly BuildSoftware vpnserver_linux_mipsel_ja = public static readonly BuildSoftware vpnserver_linux_mipsel_ja =
new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.mipsel, OSList.Linux, new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.mipsel, OSList.Linux,
@ -173,10 +177,6 @@ namespace BuildUtil
new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.ppc32, OSList.Linux, new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.ppc32, OSList.Linux,
"linux-ppc-32bit", false, "linux-ppc-32bit-3.4.6", false, "linux-ppc-32bit", false, "linux-ppc-32bit-3.4.6", false,
null); null);
public static readonly BuildSoftware vpnserver_linux_sh4_ja =
new BuildSoftwareUnix(Software.vpnserver, 0, 0, "", CpuList.sh4, OSList.Linux,
"linux-sh4-32bit", false, "linux-sh4-32bit-3.4.6", false,
null);
// Client // Client
public static readonly BuildSoftware vpnclient_linux_x86_ja = public static readonly BuildSoftware vpnclient_linux_x86_ja =
@ -193,7 +193,11 @@ namespace BuildUtil
null); null);
public static readonly BuildSoftware vpnclient_linux_armeabi_ja = public static readonly BuildSoftware vpnclient_linux_armeabi_ja =
new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.armeabi, OSList.Linux, new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.armeabi, OSList.Linux,
"linux-armeabi-32bit", false, "linux-armeabi-32bit-4.3.2", true, "linux-armeabi-32bit", false, "linux-armeabi-32bit-4.3.2", false,
null);
public static readonly BuildSoftware vpnclient_linux_arm64_ja =
new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.arm64, OSList.Linux,
"linux-arm64-64bit", false, "linux-arm64-64bit-4.8.4", false,
null); null);
public static readonly BuildSoftware vpnclient_linux_mipsel_ja = public static readonly BuildSoftware vpnclient_linux_mipsel_ja =
new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.mipsel, OSList.Linux, new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.mipsel, OSList.Linux,
@ -203,10 +207,6 @@ namespace BuildUtil
new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.ppc32, OSList.Linux, new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.ppc32, OSList.Linux,
"linux-ppc-32bit", false, "linux-ppc-32bit-3.4.6", false, "linux-ppc-32bit", false, "linux-ppc-32bit-3.4.6", false,
null); null);
public static readonly BuildSoftware vpnclient_linux_sh4_ja =
new BuildSoftwareUnix(Software.vpnclient, 0, 0, "", CpuList.sh4, OSList.Linux,
"linux-sh4-32bit", false, "linux-sh4-32bit-3.4.6", false,
null);
// Bridge // Bridge
public static readonly BuildSoftware vpnbridge_linux_x86_ja = public static readonly BuildSoftware vpnbridge_linux_x86_ja =
@ -223,7 +223,11 @@ namespace BuildUtil
null); null);
public static readonly BuildSoftware vpnbridge_linux_armeabi_ja = public static readonly BuildSoftware vpnbridge_linux_armeabi_ja =
new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.armeabi, OSList.Linux, new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.armeabi, OSList.Linux,
"linux-armeabi-32bit", false, "linux-armeabi-32bit-4.3.2", true, "linux-armeabi-32bit", false, "linux-armeabi-32bit-4.3.2", false,
null);
public static readonly BuildSoftware vpnbridge_linux_arm64_ja =
new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.arm64, OSList.Linux,
"linux-arm64-64bit", false, "linux-arm64-64bit-4.8.4", false,
null); null);
public static readonly BuildSoftware vpnbridge_linux_mipsel_ja = public static readonly BuildSoftware vpnbridge_linux_mipsel_ja =
new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.mipsel, OSList.Linux, new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.mipsel, OSList.Linux,
@ -233,10 +237,6 @@ namespace BuildUtil
new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.ppc32, OSList.Linux, new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.ppc32, OSList.Linux,
"linux-ppc-32bit", false, "linux-ppc-32bit-3.4.6", false, "linux-ppc-32bit", false, "linux-ppc-32bit-3.4.6", false,
null); null);
public static readonly BuildSoftware vpnbridge_linux_sh4_ja =
new BuildSoftwareUnix(Software.vpnbridge, 0, 0, "", CpuList.sh4, OSList.Linux,
"linux-sh4-32bit", false, "linux-sh4-32bit-3.4.6", false,
null);
// ========== FreeBSD ========== // ========== FreeBSD ==========
@ -421,7 +421,7 @@ namespace BuildUtil
{ {
// Windows // Windows
public static readonly OS Windows = new OS("windows", "Windows", public static readonly OS Windows = new OS("windows", "Windows",
"Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016", "Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Vista SP1, SP2 / 7 SP1 / 8 / 8.1 / 10 / 11 / Server 2003 SP2 / Server 2008 SP1, SP2 / Hyper-V Server 2008 / Server 2008 R2 SP1 / Hyper-V Server 2008 R2 / Server 2012 / Hyper-V Server 2012 / Server 2012 R2 / Hyper-V Server 2012 R2 / Server 2016 / Server 2019 / Server 2022",
new Cpu[] new Cpu[]
{ {
CpuList.intel, CpuList.intel,
@ -437,9 +437,9 @@ namespace BuildUtil
CpuList.mipsel, CpuList.mipsel,
CpuList.ppc32, CpuList.ppc32,
CpuList.ppc64, CpuList.ppc64,
CpuList.sh4,
CpuList.arm, CpuList.arm,
CpuList.armeabi, CpuList.armeabi,
CpuList.arm64,
}); });
// FreeBSD // FreeBSD
@ -521,10 +521,10 @@ namespace BuildUtil
public static readonly Cpu intel = new Cpu("x86_x64", "Intel", CPUBits.Both); public static readonly Cpu intel = new Cpu("x86_x64", "Intel", CPUBits.Both);
public static readonly Cpu arm = new Cpu("arm", "ARM legacy ABI", CPUBits.Bits32); public static readonly Cpu arm = new Cpu("arm", "ARM legacy ABI", CPUBits.Bits32);
public static readonly Cpu armeabi = new Cpu("arm_eabi", "ARM EABI", CPUBits.Bits32); public static readonly Cpu armeabi = new Cpu("arm_eabi", "ARM EABI", CPUBits.Bits32);
public static readonly Cpu arm64 = new Cpu("arm64", "ARM 64bit", CPUBits.Bits64);
public static readonly Cpu mipsel = new Cpu("mips_el", "MIPS Little-Endian", CPUBits.Bits32); public static readonly Cpu mipsel = new Cpu("mips_el", "MIPS Little-Endian", CPUBits.Bits32);
public static readonly Cpu ppc32 = new Cpu("powerpc", "PowerPC", CPUBits.Bits32); public static readonly Cpu ppc32 = new Cpu("powerpc", "PowerPC", CPUBits.Bits32);
public static readonly Cpu ppc64 = new Cpu("powerpc64", "PowerPC G5", CPUBits.Bits64); public static readonly Cpu ppc64 = new Cpu("powerpc64", "PowerPC G5", CPUBits.Bits64);
public static readonly Cpu sh4 = new Cpu("sh4", "SH-4", CPUBits.Bits32);
public static readonly Cpu sparc32 = new Cpu("sparc", "SPARC", CPUBits.Bits32); public static readonly Cpu sparc32 = new Cpu("sparc", "SPARC", CPUBits.Bits32);
public static readonly Cpu sparc64 = new Cpu("sparc64", "SPARC", CPUBits.Bits64); public static readonly Cpu sparc64 = new Cpu("sparc64", "SPARC", CPUBits.Bits64);

@ -170,7 +170,7 @@ namespace BuildUtil
Win32BuildUtil.ExecCommand(vpnsetup_exe, string.Format("/SFXMODE:{1} /SFXOUT:\"{0}\"", Win32BuildUtil.ExecCommand(vpnsetup_exe, string.Format("/SFXMODE:{1} /SFXOUT:\"{0}\"",
outFileName, Software.ToString())); outFileName, Software.ToString()));
CodeSign.SignFile(outFileName, outFileName, "VPN Software", false); CodeSign.SignFile(outFileName, outFileName, "VPN Software Installer", false, true, false);
} }
} }
} }

@ -166,7 +166,7 @@ namespace BuildUtil
m.ReleaseMutex(); m.ReleaseMutex();
} }
CodeSign.SignFile(cabFileName, cabFileName, "VPN Software", false); CodeSign.SignFile(cabFileName, cabFileName, "VPN Software", false, false, false);
File.Copy(cabFileName, dstFileName, true); File.Copy(cabFileName, dstFileName, true);
} }
@ -581,6 +581,16 @@ namespace BuildUtil
return false; return false;
} }
if (Str.InStr(srcPath, @"\node_modules\", false))
{
return false;
}
if (Str.InStr(srcPath, @"\wwwroot\", false))
{
return true;
}
foreach (string ext in exts) foreach (string ext in exts)
{ {
if (srcPath.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase)) if (srcPath.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase))
@ -1030,8 +1040,8 @@ namespace BuildUtil
ExecCommand(makecat1, string.Format("\"{0}\"", cdfFileName2)); ExecCommand(makecat1, string.Format("\"{0}\"", cdfFileName2));
// sign catalog file // sign catalog file
CodeSign.SignFile(catFileName, catFileName, "Catalog File", false); CodeSign.SignFile(catFileName, catFileName, "Catalog File", false, false, false);
CodeSign.SignFile(catFileName2, catFileName2, "Catalog File", false); CodeSign.SignFile(catFileName2, catFileName2, "Catalog File", false, false, false);
// delete cdf file // delete cdf file
File.Delete(cdfFileName); File.Delete(cdfFileName);
@ -1128,7 +1138,7 @@ namespace BuildUtil
if (no_sign == false) if (no_sign == false)
{ {
CodeSign.SignFile(catname, catname, "Catalog File", false); CodeSign.SignFile(catname, catname, "Catalog File", false, false, true);
} }
File.Delete(cdf_file_name); File.Delete(cdf_file_name);
@ -1387,7 +1397,7 @@ namespace BuildUtil
{ {
Con.WriteLine("Signing..."); Con.WriteLine("Signing...");
CodeSign.SignFile(file, file, "VPN Software", isDriver); CodeSign.SignFile(file, file, "VPN Software", isDriver, false, false);
} }
} }
} }
@ -1435,7 +1445,7 @@ namespace BuildUtil
Con.WriteLine("Signing..."); Con.WriteLine("Signing...");
CodeSign.SignFile(filename, filename, "VPN Software", isDriver); CodeSign.SignFile(filename, filename, "VPN Software", isDriver, false, false);
} }
} }
} }

@ -1439,3 +1439,50 @@ int CompareUserName(void *p1, void *p2)
return StrCmpi(u1->Name, u2->Name); return StrCmpi(u1->Name, u2->Name);
} }
// Get the MAC address from the user's note string
bool GetUserMacAddressFromUserNote(UCHAR *mac, wchar_t *note)
{
bool ret = false;
UINT i;
Zero(mac, 6);
if (mac == NULL || note == NULL)
{
return false;
}
i = UniSearchStrEx(note, USER_MAC_STR_PREFIX, 0, false);
if (i != INFINITE)
{
wchar_t *macstr_start = &note[i + UniStrLen(USER_MAC_STR_PREFIX)];
wchar_t macstr2[MAX_SIZE];
UNI_TOKEN_LIST *tokens;
UniStrCpy(macstr2, sizeof(macstr2), macstr_start);
UniTrim(macstr2);
tokens = UniParseToken(macstr2, L" ,/()[].");
if (tokens != NULL)
{
if (tokens->NumTokens >= 1)
{
wchar_t *macstr = tokens->Token[0];
if (UniIsEmptyStr(macstr) == false)
{
char macstr_a[MAX_SIZE];
UniToStr(macstr_a, sizeof(macstr_a), macstr);
ret = StrToMac(mac, macstr_a);
}
}
UniFreeToken(tokens);
}
}
return ret;
}

@ -105,6 +105,8 @@
#ifndef ACCOUNT_H #ifndef ACCOUNT_H
#define ACCOUNT_H #define ACCOUNT_H
#define USER_MAC_STR_PREFIX L"MAC:"
// Policy item // Policy item
struct POLICY_ITEM struct POLICY_ITEM
{ {
@ -303,6 +305,7 @@ POLICY_ITEM *GetPolicyItem(UINT id);
void GetPolicyValueRangeStr(wchar_t *str, UINT size, UINT id); void GetPolicyValueRangeStr(wchar_t *str, UINT size, UINT id);
void FormatPolicyValue(wchar_t *str, UINT size, UINT id, UINT value); void FormatPolicyValue(wchar_t *str, UINT size, UINT id, UINT value);
char *NormalizePolicyName(char *name); char *NormalizePolicyName(char *name);
bool GetUserMacAddressFromUserNote(UCHAR *mac, wchar_t *note);
#endif // ACCOUNT_H #endif // ACCOUNT_H

File diff suppressed because it is too large Load Diff

@ -129,6 +129,8 @@ struct ADMIN
LIST *LogFileList; // Accessible log file list LIST *LogFileList; // Accessible log file list
UINT ClientBuild; // Build number of the client UINT ClientBuild; // Build number of the client
RPC_WINVER ClientWinVer; // Windows version of client RPC_WINVER ClientWinVer; // Windows version of client
UINT MaxJsonRpcRecvSize; // Max JSON-RPC Receive Size
char dummy1[MAX_HUBNAME_LEN + 1]; // hubname buffer (dummy)
}; };
// Test // Test
@ -215,7 +217,8 @@ struct RPC_INT
// Set Password // Set Password
struct RPC_SET_PASSWORD struct RPC_SET_PASSWORD
{ {
UCHAR HashedPassword[SHA1_SIZE]; // Hashed password UCHAR HashedPassword[SHA1_SIZE]; // Hashed password (for traditional RPC)
char PlainTextPassword[MAX_SIZE]; // Plaintext password (for JSON-RPC)
}; };
// Server farm configuration * // Server farm configuration *
@ -228,6 +231,7 @@ struct RPC_FARM
char ControllerName[MAX_HOST_NAME_LEN + 1]; // Controller name char ControllerName[MAX_HOST_NAME_LEN + 1]; // Controller name
UINT ControllerPort; // Controller port UINT ControllerPort; // Controller port
UCHAR MemberPassword[SHA1_SIZE]; // Member password UCHAR MemberPassword[SHA1_SIZE]; // Member password
char MemberPasswordPlaintext[MAX_SIZE]; // Member password (plaintext)
UINT Weight; // Performance ratio UINT Weight; // Performance ratio
bool ControllerOnly; // Only controller function bool ControllerOnly; // Only controller function
}; };
@ -333,6 +337,7 @@ struct RPC_CREATE_HUB
char HubName[MAX_HUBNAME_LEN + 1]; // HUB Name char HubName[MAX_HUBNAME_LEN + 1]; // HUB Name
UCHAR HashedPassword[SHA1_SIZE]; // Administrative password UCHAR HashedPassword[SHA1_SIZE]; // Administrative password
UCHAR SecurePassword[SHA1_SIZE]; // Administrator password UCHAR SecurePassword[SHA1_SIZE]; // Administrator password
char AdminPasswordPlainText[MAX_SIZE]; // Password (plaintext)
bool Online; // Online flag bool Online; // Online flag
RPC_HUB_OPTION HubOption; // HUB options RPC_HUB_OPTION HubOption; // HUB options
UINT HubType; // Type of HUB UINT HubType; // Type of HUB
@ -650,6 +655,7 @@ struct RPC_ENUM_SESSION_ITEM
char RemoteHostname[MAX_HOST_NAME_LEN + 1]; // Remote server name char RemoteHostname[MAX_HOST_NAME_LEN + 1]; // Remote server name
char Username[MAX_USERNAME_LEN + 1]; // User name char Username[MAX_USERNAME_LEN + 1]; // User name
UINT Ip; // IP address (IPv4) UINT Ip; // IP address (IPv4)
IP ClientIP; // IP address (IPv4 / IPv6)
char Hostname[MAX_HOST_NAME_LEN + 1]; // Host name char Hostname[MAX_HOST_NAME_LEN + 1]; // Host name
UINT MaxNumTcp; // Maximum number of TCP connections UINT MaxNumTcp; // Maximum number of TCP connections
UINT CurrentNumTcp; // Number of currentl TCP connections UINT CurrentNumTcp; // Number of currentl TCP connections
@ -666,6 +672,8 @@ struct RPC_ENUM_SESSION_ITEM
bool IsDormantEnabled; // Is the dormant state enabled bool IsDormantEnabled; // Is the dormant state enabled
bool IsDormant; // Is in the dormant state bool IsDormant; // Is in the dormant state
UINT64 LastCommDormant; // Last comm interval in the dormant state UINT64 LastCommDormant; // Last comm interval in the dormant state
UINT64 CreatedTime; // Creation date and time
UINT64 LastCommTime; // Last communication date and time
}; };
// Disconnect the session // Disconnect the session
@ -702,8 +710,9 @@ struct RPC_ENUM_IP_TABLE_ITEM
{ {
UINT Key; // Key UINT Key; // Key
char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name
UINT Ip; // IP address UINT Ip; // IPv4 address
IP IpV6; // IPv6 address IP IpV6; // IPv6 address
IP IpAddress; // IPv4 / IPv6 Address
bool DhcpAllocated; // Assigned by the DHCP bool DhcpAllocated; // Assigned by the DHCP
UINT64 CreatedTime; // Creation date and time UINT64 CreatedTime; // Creation date and time
UINT64 UpdatedTime; // Updating date UINT64 UpdatedTime; // Updating date
@ -990,6 +999,11 @@ struct RPC_AZURE_STATUS
}; };
// Constants
#define ADMIN_RPC_MAX_POST_SIZE_BY_SERVER_ADMIN MAX_PACK_SIZE
#define ADMIN_RPC_MAX_POST_SIZE_BY_HUB_ADMIN (8 * 1024 * 1024)
// Function prototype // Function prototype
UINT AdminAccept(CONNECTION *c, PACK *p); UINT AdminAccept(CONNECTION *c, PACK *p);
void HashAdminPassword(void *hash, char *password); void HashAdminPassword(void *hash, char *password);
@ -1014,6 +1028,26 @@ BUF *DownloadFileFromServer(RPC *r, char *server_name, char *filepath, UINT tota
bool CheckAdminSourceAddress(SOCK *sock, char *hubname); bool CheckAdminSourceAddress(SOCK *sock, char *hubname);
void SiEnumSessionMain(SERVER *s, RPC_ENUM_SESSION *t); void SiEnumSessionMain(SERVER *s, RPC_ENUM_SESSION *t);
bool SiIsEmptyPassword(void *hash_password); bool SiIsEmptyPassword(void *hash_password);
void JsonRpcProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size);
void JsonRpcProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target);
void JsonRpcProcOptions(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target);
JSON_VALUE *JsonRpcProcRequestObject(ADMIN *admin, CONNECTION *c, SOCK *s, JSON_VALUE *json_req, char *method_name);
JSON_VALUE *JsonRpcNewError(int code, wchar_t *message);
JSON_VALUE *JsonRpcNewResponse(PACK *p);
bool HttpParseBasicAuthHeader(HTTP_HEADER *h, char *username, UINT username_size, char *password, UINT password_size);
ADMIN *JsonRpcAuthLogin(CEDAR *c, SOCK *sock, HTTP_HEADER *h);
JSON_VALUE *QueryStringToJsonListValue(char *qs);
JSON_VALUE *ConstructDummyJsonRpcRequest(char *method_name, JSON_VALUE *p);
void AdminWebProcPost(CONNECTION *c, SOCK *s, HTTP_HEADER *h, UINT post_data_size, char *url_target);
void AdminWebProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target);
bool AdminWebHandleFileRequest(ADMIN *a, CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_src, char *query_string, char *virtual_root_dir, char *physical_root_dir);
BUF *AdminWebProcessServerSideInclude(BUF *src_txt, char *filename, UINT depth);
bool AdminWebSendBody(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type, char *add_header_name, char *add_header_value, HTTP_HEADER *request_headers);
bool AdminWebSend404Error(SOCK *s, HTTP_HEADER *request_headers);
bool AdminWebSend302Redirect(SOCK *s, char *url, char *query_string, HTTP_HEADER *request_headers);
BUF *AdminWebTryFindAndReadFile(char *vroot, char *proot, char *url, char *ret_filename, UINT ret_filename_size, bool *is_index_html);
BUF *AdminWebTryOneFile(char *filename, char *ret_filename, UINT ret_filename_size);
bool AdminWebSendUnauthorized(SOCK *s, HTTP_HEADER *http_request_headers);
UINT StTest(ADMIN *a, RPC_TEST *t); UINT StTest(ADMIN *a, RPC_TEST *t);
UINT StGetServerInfo(ADMIN *a, RPC_SERVER_INFO *t); UINT StGetServerInfo(ADMIN *a, RPC_SERVER_INFO *t);
@ -1387,7 +1421,7 @@ void OutRpcAccess(PACK *p, ACCESS *a);
void InRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a, PACK *p); void InRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a, PACK *p);
void OutRpcEnumAccessList(PACK *p, RPC_ENUM_ACCESS_LIST *a); void OutRpcEnumAccessList(PACK *p, RPC_ENUM_ACCESS_LIST *a);
void FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a); void FreeRpcEnumAccessList(RPC_ENUM_ACCESS_LIST *a);
void *InRpcAuthData(PACK *p, UINT *authtype); void *InRpcAuthData(PACK *p, UINT *authtype, char *username);
void OutRpcAuthData(PACK *p, void *authdata, UINT authtype); void OutRpcAuthData(PACK *p, void *authdata, UINT authtype);
void FreeRpcAuthData(void *authdata, UINT authtype); void FreeRpcAuthData(void *authdata, UINT authtype);
void InRpcSetUser(RPC_SET_USER *t, PACK *p); void InRpcSetUser(RPC_SET_USER *t, PACK *p);

@ -184,7 +184,7 @@ void AcWaitForRequest(AZURE_CLIENT *ac, SOCK *s, AZURE_PARAM *param)
SetTimeout(ns, param->DataTimeout); SetTimeout(ns, param->DataTimeout);
if (StartSSLEx(ns, NULL, NULL, true, 0, NULL)) if (StartSSLEx(ns, NULL, NULL, true, 0, NULL)) // DO NOT SET SNI Hostname !!
{ {
// Check certification // Check certification
char server_cert_hash_str[MAX_SIZE]; char server_cert_hash_str[MAX_SIZE];

@ -526,7 +526,7 @@ void CmEasyDlgOnKey(HWND hWnd, CM_EASY_DLG *d, bool ctrl, bool alt, UINT key)
break; break;
case 'O': case 'O':
// Option settings // Option settings
Command(hWnd, CMD_TRAFFIC); Command(hWnd, CMD_OPTION);
break; break;
case 'R': case 'R':
// Certificate management // Certificate management
@ -4387,7 +4387,10 @@ UINT CmMainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, void *p
switch (wParam) switch (wParam)
{ {
case 1: case 1:
if (MsIsWindows11() == false)
{
CmSetForegroundProcessToCnService(); CmSetForegroundProcessToCnService();
}
break; break;
case 2: case 2:
CmPollingTray(hWnd); CmPollingTray(hWnd);
@ -5164,7 +5167,7 @@ void CmOnKey(HWND hWnd, bool ctrl, bool alt, UINT key)
break; break;
case 'O': case 'O':
// Option settings // Option settings
Command(hWnd, CMD_TRAFFIC); Command(hWnd, CMD_OPTION);
break; break;
case 'R': case 'R':
// Certificate management // Certificate management
@ -5907,6 +5910,7 @@ void CmConfigDlgInit(HWND hWnd)
} }
Check(hWnd, R_ALLOW_REMOTE_CONFIG, c.AllowRemoteConfig); Check(hWnd, R_ALLOW_REMOTE_CONFIG, c.AllowRemoteConfig);
Check(hWnd, R_TUNNELCRACK, c.EnableTunnelCrackProtect);
Check(hWnd, R_USE_KEEP_CONNECT, c.UseKeepConnect); Check(hWnd, R_USE_KEEP_CONNECT, c.UseKeepConnect);
SetTextA(hWnd, E_HOSTNAME, c.KeepConnectHost); SetTextA(hWnd, E_HOSTNAME, c.KeepConnectHost);
@ -5933,6 +5937,15 @@ void CmConfigDlgInit(HWND hWnd)
Disable(hWnd, R_ALPHA); Disable(hWnd, R_ALPHA);
} }
if (OS_IS_WINDOWS_NT(cm->Client->OsType))
{
Enable(hWnd, R_TUNNELCRACK);
}
else
{
Disable(hWnd, R_TUNNELCRACK);
}
CmConfigDlgRefresh(hWnd); CmConfigDlgRefresh(hWnd);
} }
@ -6012,6 +6025,7 @@ void CmConfigDlgOnOk(HWND hWnd)
Zero(&c, sizeof(c)); Zero(&c, sizeof(c));
c.AllowRemoteConfig = IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG); c.AllowRemoteConfig = IsChecked(hWnd, R_ALLOW_REMOTE_CONFIG);
c.EnableTunnelCrackProtect = IsChecked(hWnd, R_TUNNELCRACK);
c.UseKeepConnect = IsChecked(hWnd, R_USE_KEEP_CONNECT); c.UseKeepConnect = IsChecked(hWnd, R_USE_KEEP_CONNECT);
GetTxtA(hWnd, E_HOSTNAME, c.KeepConnectHost, sizeof(c.KeepConnectHost)); GetTxtA(hWnd, E_HOSTNAME, c.KeepConnectHost, sizeof(c.KeepConnectHost));
c.KeepConnectPort = GetInt(hWnd, E_PORT); c.KeepConnectPort = GetInt(hWnd, E_PORT);
@ -9466,6 +9480,12 @@ void CmPrintStatusToListViewEx(LVB *b, RPC_CLIENT_GET_CONNECTION_STATUS *s, bool
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp); LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp);
} }
if (IsEmptyStr(s->ProtocolDetails) == false)
{
StrToUni(tmp, sizeof(tmp), s->ProtocolDetails);
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_PROTOCOL_DETAILS"), tmp);
}
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); LvInsertAdd(b, 0, NULL, 2, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
@ -11178,7 +11198,10 @@ void CmMainWindowOnInit(HWND hWnd)
CmInitNotifyClientThread(); CmInitNotifyClientThread();
// Timer setting // Timer setting
if (MsIsWindows11() == false)
{
SetTimer(hWnd, 1, 128, NULL); SetTimer(hWnd, 1, 128, NULL);
}
SetTimer(hWnd, 6, 5000, NULL); SetTimer(hWnd, 6, 5000, NULL);
// Initialize the task tray // Initialize the task tray

@ -1680,6 +1680,7 @@ CEDAR *NewCedar(X *server_x, K *server_k)
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
char tmp2[MAX_SIZE]; char tmp2[MAX_SIZE];
char *beta_str; char *beta_str;
char ssl_lib_ver[MAX_PATH] = CLEAN;
CedarForceLink(); CedarForceLink();
@ -1798,8 +1799,10 @@ CEDAR *NewCedar(X *server_x, K *server_k)
c->VerString = CopyStr(tmp); c->VerString = CopyStr(tmp);
Format(tmp, sizeof(tmp), "Compiled %04u/%02u/%02u %02u:%02u:%02u by %s at %s", GetSslLibVersion(ssl_lib_ver, sizeof(ssl_lib_ver));
BUILD_DATE_Y, BUILD_DATE_M, BUILD_DATE_D, BUILD_DATE_HO, BUILD_DATE_MI, BUILD_DATE_SE, BUILDER_NAME, BUILD_PLACE);
Format(tmp, sizeof(tmp), "Compiled %04u/%02u/%02u %02u:%02u:%02u by %s at %s with %s",
BUILD_DATE_Y, BUILD_DATE_M, BUILD_DATE_D, BUILD_DATE_HO, BUILD_DATE_MI, BUILD_DATE_SE, BUILDER_NAME, BUILD_PLACE, ssl_lib_ver);
c->BuildInfo = CopyStr(tmp); c->BuildInfo = CopyStr(tmp);

@ -126,10 +126,10 @@
// Version number // Version number
#define CEDAR_VER 429 #define CEDAR_VER 444
// Build Number // Build Number
#define CEDAR_BUILD 9680 #define CEDAR_BUILD 9807
// Beta number // Beta number
//#define BETA_NUMBER 3 //#define BETA_NUMBER 3
@ -139,21 +139,21 @@
// Specify the name of the person in charge building // Specify the name of the person in charge building
#ifndef BUILDER_NAME #ifndef BUILDER_NAME
#define BUILDER_NAME "yagi" #define BUILDER_NAME "buildsan"
#endif // BUILDER_NAME #endif // BUILDER_NAME
// Specify the location to build // Specify the location to build
#ifndef BUILD_PLACE #ifndef BUILD_PLACE
#define BUILD_PLACE "pc33" #define BUILD_PLACE "crosswin"
#endif // BUILD_PLACE #endif // BUILD_PLACE
// Specifies the build date // Specifies the build date
#define BUILD_DATE_Y 2019 #define BUILD_DATE_Y 2025
#define BUILD_DATE_M 2 #define BUILD_DATE_M 4
#define BUILD_DATE_D 28 #define BUILD_DATE_D 16
#define BUILD_DATE_HO 18 #define BUILD_DATE_HO 4
#define BUILD_DATE_MI 39 #define BUILD_DATE_MI 30
#define BUILD_DATE_SE 47 #define BUILD_DATE_SE 26
// Tolerable time difference // Tolerable time difference
#define ALLOW_TIMESTAMP_DIFF (UINT64)(3 * 24 * 60 * 60 * 1000) #define ALLOW_TIMESTAMP_DIFF (UINT64)(3 * 24 * 60 * 60 * 1000)
@ -183,7 +183,6 @@
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#define MAX_ACCOUNT_NAME_LEN 255 // Maximum account name length #define MAX_ACCOUNT_NAME_LEN 255 // Maximum account name length
#define MAX_USERNAME_LEN 255 // User name maximum length
#define MAX_PASSWORD_LEN 255 // Password name maximum length #define MAX_PASSWORD_LEN 255 // Password name maximum length
#define MAX_PROXY_USERNAME_LEN 255 // Proxy user name maximum length #define MAX_PROXY_USERNAME_LEN 255 // Proxy user name maximum length
#define MAX_PROXY_PASSWORD_LEN 255 // Proxy Password maximum length #define MAX_PROXY_PASSWORD_LEN 255 // Proxy Password maximum length
@ -194,10 +193,8 @@
#define MAX_CONNECTION_NAME_LEN 255 // Maximum length of connection name #define MAX_CONNECTION_NAME_LEN 255 // Maximum length of connection name
#define MAX_DEVICE_NAME_LEN 31 // Device name maximum length #define MAX_DEVICE_NAME_LEN 31 // Device name maximum length
#define MAX_DEVICE_NAME_LEN_9X 4 // Maximum length of Virtual LAN card name in Win9x #define MAX_DEVICE_NAME_LEN_9X 4 // Maximum length of Virtual LAN card name in Win9x
#define MAX_ACCESSLIST_NOTE_LEN 255 // Maximum length of the note of access list entry
#define MAX_SECURE_DEVICE_FILE_LEN 255 // Secure device file name maximum length #define MAX_SECURE_DEVICE_FILE_LEN 255 // Secure device file name maximum length
#define MAX_ADMIN_OPTION_NAME_LEN 63 // Management option name #define MAX_ADMIN_OPTION_NAME_LEN 63 // Management option name
#define MAX_REDIRECT_URL_LEN 255 // URL length to redirect
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@ -438,6 +435,7 @@
#define AUTHTYPE_ROOTCERT 3 // Root certificate which is issued by trusted Certificate Authority #define AUTHTYPE_ROOTCERT 3 // Root certificate which is issued by trusted Certificate Authority
#define AUTHTYPE_RADIUS 4 // Radius authentication #define AUTHTYPE_RADIUS 4 // Radius authentication
#define AUTHTYPE_NT 5 // Windows NT authentication #define AUTHTYPE_NT 5 // Windows NT authentication
#define AUTHTYPE_OPENVPN_CERT 98 // TLS client certificate authentication
#define AUTHTYPE_TICKET 99 // Ticket authentication #define AUTHTYPE_TICKET 99 // Ticket authentication
// Constant of the client side // Constant of the client side
@ -933,6 +931,7 @@
#define ERR_VPNGATE_INCLIENT_CANT_STOP 146 // Can not be stopped if operating within VPN Client mode #define ERR_VPNGATE_INCLIENT_CANT_STOP 146 // Can not be stopped if operating within VPN Client mode
#define ERR_NOT_SUPPORTED_FUNCTION_ON_OPENSOURCE 147 // It is a feature that is not supported in the open source version #define ERR_NOT_SUPPORTED_FUNCTION_ON_OPENSOURCE 147 // It is a feature that is not supported in the open source version
#define ERR_SUSPENDING 148 // System is suspending #define ERR_SUSPENDING 148 // System is suspending
#define ERR_DHCP_SERVER_NOT_RUNNING 149 // DHCP server is not running
//////////////////////////// ////////////////////////////

@ -70,6 +70,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalOptions="/IGNORE:4006,4221"
AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)" AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)"
/> />
<Tool <Tool
@ -140,6 +141,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalOptions="/IGNORE:4006,4221"
AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)" AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)"
/> />
<Tool <Tool
@ -213,6 +215,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalOptions="/IGNORE:4006,4221"
AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)" AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)"
/> />
<Tool <Tool
@ -287,6 +290,7 @@
/> />
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalOptions="/IGNORE:4006,4221"
AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)" AdditionalLibraryDirectories="$(SolutionDir)BuildFiles\Library\$(PlatformName)_$(ConfigurationName)"
/> />
<Tool <Tool

@ -213,7 +213,6 @@ typedef struct HUB_OPTION HUB_OPTION;
typedef struct MAC_TABLE_ENTRY MAC_TABLE_ENTRY; typedef struct MAC_TABLE_ENTRY MAC_TABLE_ENTRY;
typedef struct IP_TABLE_ENTRY IP_TABLE_ENTRY; typedef struct IP_TABLE_ENTRY IP_TABLE_ENTRY;
typedef struct LOOP_LIST LOOP_LIST; typedef struct LOOP_LIST LOOP_LIST;
typedef struct ACCESS ACCESS;
typedef struct TICKET TICKET; typedef struct TICKET TICKET;
typedef struct TRAFFIC_DIFF TRAFFIC_DIFF; typedef struct TRAFFIC_DIFF TRAFFIC_DIFF;
typedef struct HUB HUB; typedef struct HUB HUB;
@ -234,6 +233,9 @@ typedef struct BLACK BLACK;
typedef struct SEND_SIGNATURE_PARAM SEND_SIGNATURE_PARAM; typedef struct SEND_SIGNATURE_PARAM SEND_SIGNATURE_PARAM;
typedef struct UPDATE_CLIENT UPDATE_CLIENT; typedef struct UPDATE_CLIENT UPDATE_CLIENT;
typedef struct UPDATE_CLIENT_SETTING UPDATE_CLIENT_SETTING; typedef struct UPDATE_CLIENT_SETTING UPDATE_CLIENT_SETTING;
typedef struct HTTP_MIME_TYPE HTTP_MIME_TYPE;
typedef struct WS WS;
typedef struct WSP WSP;
// ============================================================== // ==============================================================
@ -613,6 +615,7 @@ typedef struct IKE_SA_TRANSFORM_SETTING IKE_SA_TRANSFORM_SETTING;
typedef struct IKE_CLIENT IKE_CLIENT; typedef struct IKE_CLIENT IKE_CLIENT;
typedef struct IPSECSA IPSECSA; typedef struct IPSECSA IPSECSA;
typedef struct IKE_CAPS IKE_CAPS; typedef struct IKE_CAPS IKE_CAPS;
typedef struct IKE_INFOMSG_QUOTA_ENTRY IKE_INFOMSG_QUOTA_ENTRY;
// ============================================================== // ==============================================================
// IPSec Packet // IPSec Packet
@ -673,6 +676,7 @@ typedef struct IPC_ASYNC IPC_ASYNC;
typedef struct IPC_PARAM IPC_PARAM; typedef struct IPC_PARAM IPC_PARAM;
typedef struct IPC_DHCP_RELESAE_QUEUE IPC_DHCP_RELESAE_QUEUE; typedef struct IPC_DHCP_RELESAE_QUEUE IPC_DHCP_RELESAE_QUEUE;
typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO; typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO;
typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA;
// ============================================================== // ==============================================================

@ -3935,6 +3935,7 @@ void InRpcClientConfig(CLIENT_CONFIG *c, PACK *p)
c->KeepConnectProtocol = PackGetInt(p, "KeepConnectProtocol"); c->KeepConnectProtocol = PackGetInt(p, "KeepConnectProtocol");
c->KeepConnectInterval = PackGetInt(p, "KeepConnectInterval"); c->KeepConnectInterval = PackGetInt(p, "KeepConnectInterval");
c->AllowRemoteConfig = PackGetInt(p, "AllowRemoteConfig") == 0 ? false : true; c->AllowRemoteConfig = PackGetInt(p, "AllowRemoteConfig") == 0 ? false : true;
c->EnableTunnelCrackProtect = PackGetInt(p, "EnableTunnelCrackProtect") == 0 ? false : true;
PackGetStr(p, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost)); PackGetStr(p, "KeepConnectHost", c->KeepConnectHost, sizeof(c->KeepConnectHost));
} }
void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c) void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c)
@ -3950,6 +3951,7 @@ void OutRpcClientConfig(PACK *p, CLIENT_CONFIG *c)
PackAddInt(p, "KeepConnectProtocol", c->KeepConnectProtocol); PackAddInt(p, "KeepConnectProtocol", c->KeepConnectProtocol);
PackAddInt(p, "KeepConnectInterval", c->KeepConnectInterval); PackAddInt(p, "KeepConnectInterval", c->KeepConnectInterval);
PackAddInt(p, "AllowRemoteConfig", c->AllowRemoteConfig); PackAddInt(p, "AllowRemoteConfig", c->AllowRemoteConfig);
PackAddInt(p, "EnableTunnelCrackProtect", c->EnableTunnelCrackProtect);
PackAddStr(p, "KeepConnectHost", c->KeepConnectHost); PackAddStr(p, "KeepConnectHost", c->KeepConnectHost);
} }
@ -4083,14 +4085,16 @@ void OutRpcClientEnumCa(PACK *p, RPC_CLIENT_ENUM_CA *e)
PackAddNum(p, "NumItem", e->NumItem); PackAddNum(p, "NumItem", e->NumItem);
PackSetCurrentJsonGroupName(p, "CAList");
for (i = 0;i < e->NumItem;i++) for (i = 0;i < e->NumItem;i++)
{ {
RPC_CLIENT_ENUM_CA_ITEM *item = e->Items[i]; RPC_CLIENT_ENUM_CA_ITEM *item = e->Items[i];
PackAddIntEx(p, "Key", item->Key, i, e->NumItem); PackAddIntEx(p, "Key", item->Key, i, e->NumItem);
PackAddUniStrEx(p, "SubjectName", item->SubjectName, i, e->NumItem); PackAddUniStrEx(p, "SubjectName", item->SubjectName, i, e->NumItem);
PackAddUniStrEx(p, "IssuerName", item->IssuerName, i, e->NumItem); PackAddUniStrEx(p, "IssuerName", item->IssuerName, i, e->NumItem);
PackAddInt64Ex(p, "Expires", item->Expires, i, e->NumItem); PackAddTime64Ex(p, "Expires", item->Expires, i, e->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
} }
// RPC_GET_ISSUER // RPC_GET_ISSUER
@ -4361,6 +4365,7 @@ void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e)
PackAddNum(p, "NumItem", e->NumItem); PackAddNum(p, "NumItem", e->NumItem);
PackSetCurrentJsonGroupName(p, "SecureDeviceList");
for (i = 0;i < e->NumItem;i++) for (i = 0;i < e->NumItem;i++)
{ {
RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i]; RPC_CLIENT_ENUM_SECURE_ITEM *item = e->Items[i];
@ -4370,6 +4375,7 @@ void OutRpcClientEnumSecure(PACK *p, RPC_CLIENT_ENUM_SECURE *e)
PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem); PackAddStrEx(p, "DeviceName", item->DeviceName, i, e->NumItem);
PackAddStrEx(p, "Manufacturer", item->Manufacturer, i, e->NumItem); PackAddStrEx(p, "Manufacturer", item->Manufacturer, i, e->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
} }
// RPC_USE_SECURE // RPC_USE_SECURE
@ -4453,11 +4459,13 @@ void OutRpcEnumObjectInSecure(PACK *p, RPC_ENUM_OBJECT_IN_SECURE *e)
PackAddNum(p, "NumItem", e->NumItem); PackAddNum(p, "NumItem", e->NumItem);
PackAddInt(p, "hWnd", e->hWnd); PackAddInt(p, "hWnd", e->hWnd);
PackSetCurrentJsonGroupName(p, "ObjectList");
for (i = 0;i < e->NumItem;i++) for (i = 0;i < e->NumItem;i++)
{ {
PackAddStrEx(p, "ItemName", e->ItemName[i], i, e->NumItem); PackAddStrEx(p, "ItemName", e->ItemName[i], i, e->NumItem);
PackAddIntEx(p, "ItemType", e->ItemType[i], i, e->NumItem); PackAddIntEx(p, "ItemType", e->ItemType[i], i, e->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
} }
// RPC_CLIENT_CREATE_VLAN // RPC_CLIENT_CREATE_VLAN
@ -4577,6 +4585,7 @@ void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v)
PackAddNum(p, "NumItem", v->NumItem); PackAddNum(p, "NumItem", v->NumItem);
PackSetCurrentJsonGroupName(p, "VLanList");
for (i = 0;i < v->NumItem;i++) for (i = 0;i < v->NumItem;i++)
{ {
RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i]; RPC_CLIENT_ENUM_VLAN_ITEM *item = v->Items[i];
@ -4586,6 +4595,7 @@ void OutRpcClientEnumVLan(PACK *p, RPC_CLIENT_ENUM_VLAN *v)
PackAddStrEx(p, "MacAddress", item->MacAddress, i, v->NumItem); PackAddStrEx(p, "MacAddress", item->MacAddress, i, v->NumItem);
PackAddStrEx(p, "Version", item->Version, i, v->NumItem); PackAddStrEx(p, "Version", item->Version, i, v->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
} }
// CLIENT_OPTION // CLIENT_OPTION
@ -4651,10 +4661,10 @@ void OutRpcClientOption(PACK *p, CLIENT_OPTION *c)
PackAddInt(p, "NumRetry", c->NumRetry); PackAddInt(p, "NumRetry", c->NumRetry);
PackAddInt(p, "RetryInterval", c->RetryInterval); PackAddInt(p, "RetryInterval", c->RetryInterval);
PackAddInt(p, "MaxConnection", c->MaxConnection); PackAddInt(p, "MaxConnection", c->MaxConnection);
PackAddInt(p, "UseEncrypt", c->UseEncrypt); PackAddBool(p, "UseEncrypt", c->UseEncrypt);
PackAddInt(p, "UseCompress", c->UseCompress); PackAddBool(p, "UseCompress", c->UseCompress);
PackAddInt(p, "HalfConnection", c->HalfConnection); PackAddBool(p, "HalfConnection", c->HalfConnection);
PackAddInt(p, "NoRoutingTracking", c->NoRoutingTracking); PackAddBool(p, "NoRoutingTracking", c->NoRoutingTracking);
PackAddInt(p, "AdditionalConnectionInterval", c->AdditionalConnectionInterval); PackAddInt(p, "AdditionalConnectionInterval", c->AdditionalConnectionInterval);
PackAddInt(p, "ConnectionDisconnectSpan", c->ConnectionDisconnectSpan); PackAddInt(p, "ConnectionDisconnectSpan", c->ConnectionDisconnectSpan);
PackAddBool(p, "HideStatusWindow", c->HideStatusWindow); PackAddBool(p, "HideStatusWindow", c->HideStatusWindow);
@ -4866,6 +4876,7 @@ void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e)
PackAddNum(p, "NumItem", e->NumItem); PackAddNum(p, "NumItem", e->NumItem);
PackSetCurrentJsonGroupName(p, "AccountList");
for (i = 0;i < e->NumItem;i++) for (i = 0;i < e->NumItem;i++)
{ {
RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i]; RPC_CLIENT_ENUM_ACCOUNT_ITEM *item = e->Items[i];
@ -4881,10 +4892,11 @@ void OutRpcClientEnumAccount(PACK *p, RPC_CLIENT_ENUM_ACCOUNT *e)
PackAddBoolEx(p, "Connected", item->Connected, i, e->NumItem); PackAddBoolEx(p, "Connected", item->Connected, i, e->NumItem);
PackAddIntEx(p, "Port", item->Port, i, e->NumItem); PackAddIntEx(p, "Port", item->Port, i, e->NumItem);
PackAddStrEx(p, "HubName", item->HubName, i, e->NumItem); PackAddStrEx(p, "HubName", item->HubName, i, e->NumItem);
PackAddInt64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem); PackAddTime64Ex(p, "CreateDateTime", item->CreateDateTime, i, e->NumItem);
PackAddInt64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem); PackAddTime64Ex(p, "UpdateDateTime", item->UpdateDateTime, i, e->NumItem);
PackAddInt64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem); PackAddTime64Ex(p, "LastConnectDateTime", item->LastConnectDateTime, i, e->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
} }
// RPC_CLIENT_DELETE_ACCOUNT // RPC_CLIENT_DELETE_ACCOUNT
@ -4998,9 +5010,9 @@ void OutRpcClientGetAccount(PACK *p, RPC_CLIENT_GET_ACCOUNT *c)
PackAddData(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE); PackAddData(p, "ShortcutKey", c->ShortcutKey, SHA1_SIZE);
PackAddInt64(p, "CreateDateTime", c->CreateDateTime); PackAddTime64(p, "CreateDateTime", c->CreateDateTime);
PackAddInt64(p, "UpdateDateTime", c->UpdateDateTime); PackAddTime64(p, "UpdateDateTime", c->UpdateDateTime);
PackAddInt64(p, "LastConnectDateTime", c->LastConnectDateTime); PackAddTime64(p, "LastConnectDateTime", c->LastConnectDateTime);
} }
// RPC_CLIENT_CONNECT // RPC_CLIENT_CONNECT
@ -5103,6 +5115,7 @@ void InRpcClientGetConnectionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *s, PACK *p
s->UseCompress = PackGetInt(p, "UseCompress") ? true : false; s->UseCompress = PackGetInt(p, "UseCompress") ? true : false;
s->IsRUDPSession = PackGetInt(p, "IsRUDPSession") ? true : false; s->IsRUDPSession = PackGetInt(p, "IsRUDPSession") ? true : false;
PackGetStr(p, "UnderlayProtocol", s->UnderlayProtocol, sizeof(s->UnderlayProtocol)); PackGetStr(p, "UnderlayProtocol", s->UnderlayProtocol, sizeof(s->UnderlayProtocol));
PackGetStr(p, "ProtocolDetails", s->ProtocolDetails, sizeof(s->ProtocolDetails));
s->IsUdpAccelerationEnabled = PackGetInt(p, "IsUdpAccelerationEnabled") ? true : false; s->IsUdpAccelerationEnabled = PackGetInt(p, "IsUdpAccelerationEnabled") ? true : false;
s->IsUsingUdpAcceleration = PackGetInt(p, "IsUsingUdpAcceleration") ? true : false; s->IsUsingUdpAcceleration = PackGetInt(p, "IsUsingUdpAcceleration") ? true : false;
@ -5148,32 +5161,33 @@ void OutRpcClientGetConnectionStatus(PACK *p, RPC_CLIENT_GET_CONNECTION_STATUS *
PackAddData(p, "SessionKey", c->SessionKey, SHA1_SIZE); PackAddData(p, "SessionKey", c->SessionKey, SHA1_SIZE);
PackAddInt(p, "Active", c->Active); PackAddBool(p, "Active", c->Active);
PackAddInt(p, "Connected", c->Connected); PackAddBool(p, "Connected", c->Connected);
PackAddInt(p, "SessionStatus", c->SessionStatus); PackAddInt(p, "SessionStatus", c->SessionStatus);
PackAddInt(p, "ServerPort", c->ServerPort); PackAddInt(p, "ServerPort", c->ServerPort);
PackAddInt(p, "ServerProductVer", c->ServerProductVer); PackAddInt(p, "ServerProductVer", c->ServerProductVer);
PackAddInt(p, "ServerProductBuild", c->ServerProductBuild); PackAddInt(p, "ServerProductBuild", c->ServerProductBuild);
PackAddInt(p, "NumConnectionsEatablished", c->NumConnectionsEatablished); PackAddInt(p, "NumConnectionsEatablished", c->NumConnectionsEatablished);
PackAddInt(p, "HalfConnection", c->HalfConnection); PackAddBool(p, "HalfConnection", c->HalfConnection);
PackAddInt(p, "QoS", c->QoS); PackAddBool(p, "QoS", c->QoS);
PackAddInt(p, "MaxTcpConnections", c->MaxTcpConnections); PackAddInt(p, "MaxTcpConnections", c->MaxTcpConnections);
PackAddInt(p, "NumTcpConnections", c->NumTcpConnections); PackAddInt(p, "NumTcpConnections", c->NumTcpConnections);
PackAddInt(p, "NumTcpConnectionsUpload", c->NumTcpConnectionsUpload); PackAddInt(p, "NumTcpConnectionsUpload", c->NumTcpConnectionsUpload);
PackAddInt(p, "NumTcpConnectionsDownload", c->NumTcpConnectionsDownload); PackAddInt(p, "NumTcpConnectionsDownload", c->NumTcpConnectionsDownload);
PackAddInt(p, "UseEncrypt", c->UseEncrypt); PackAddBool(p, "UseEncrypt", c->UseEncrypt);
PackAddInt(p, "UseCompress", c->UseCompress); PackAddBool(p, "UseCompress", c->UseCompress);
PackAddInt(p, "IsRUDPSession", c->IsRUDPSession); PackAddBool(p, "IsRUDPSession", c->IsRUDPSession);
PackAddStr(p, "UnderlayProtocol", c->UnderlayProtocol); PackAddStr(p, "UnderlayProtocol", c->UnderlayProtocol);
PackAddInt(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled); PackAddStr(p, "ProtocolDetails", c->ProtocolDetails);
PackAddInt(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration); PackAddBool(p, "IsUdpAccelerationEnabled", c->IsUdpAccelerationEnabled);
PackAddBool(p, "IsUsingUdpAcceleration", c->IsUsingUdpAcceleration);
PackAddBool(p, "IsBridgeMode", c->IsBridgeMode); PackAddBool(p, "IsBridgeMode", c->IsBridgeMode);
PackAddBool(p, "IsMonitorMode", c->IsMonitorMode); PackAddBool(p, "IsMonitorMode", c->IsMonitorMode);
PackAddInt64(p, "StartTime", c->StartTime); PackAddTime64(p, "StartTime", c->StartTime);
PackAddInt64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime); PackAddTime64(p, "FirstConnectionEstablisiedTime", c->FirstConnectionEstablisiedTime);
PackAddInt64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime); PackAddTime64(p, "CurrentConnectionEstablishTime", c->CurrentConnectionEstablishTime);
PackAddInt64(p, "TotalSendSize", c->TotalSendSize); PackAddInt64(p, "TotalSendSize", c->TotalSendSize);
PackAddInt64(p, "TotalRecvSize", c->TotalRecvSize); PackAddInt64(p, "TotalRecvSize", c->TotalRecvSize);
PackAddInt64(p, "TotalSendSizeReal", c->TotalSendSizeReal); PackAddInt64(p, "TotalSendSizeReal", c->TotalSendSizeReal);
@ -5397,6 +5411,22 @@ void CiRpcAccepted(CLIENT *c, SOCK *s)
retcode = 0; retcode = 0;
} }
if (retcode == 0)
{
if (s->RemoteIP.addr[0] != 127)
{
// If the RPC client is from network check whether the password is empty
UCHAR empty_password_hash[20];
Hash(empty_password_hash, "", 0, true);
if (Cmp(empty_password_hash, hashed_password, SHA1_SIZE) == 0 ||
IsZero(hashed_password, SHA1_SIZE))
{
// Regard it as incorrect password
retcode = 1;
}
}
}
Lock(c->lock); Lock(c->lock);
{ {
if (c->Config.AllowRemoteConfig == false) if (c->Config.AllowRemoteConfig == false)
@ -5500,14 +5530,21 @@ void CiRpcServerThread(THREAD *thread, void *param)
// Open the port // Open the port
listener = NULL; listener = NULL;
if (c->Config.DisableRpcDynamicPortListener == false)
{
for (i = CLIENT_CONFIG_PORT;i < (CLIENT_CONFIG_PORT + 5);i++) for (i = CLIENT_CONFIG_PORT;i < (CLIENT_CONFIG_PORT + 5);i++)
{ {
listener = Listen(i); listener = ListenEx(i, !c->Config.AllowRemoteConfig);
if (listener != NULL) if (listener != NULL)
{ {
break; break;
} }
} }
}
else
{
listener = ListenEx(CLIENT_CONFIG_PORT, !c->Config.AllowRemoteConfig);
}
if (listener == NULL) if (listener == NULL)
{ {
@ -6124,9 +6161,23 @@ void CiGetSessionStatus(RPC_CLIENT_GET_CONNECTION_STATUS *st, SESSION *s)
st->IsRUDPSession = s->IsRUDPSession; st->IsRUDPSession = s->IsRUDPSession;
// Physical communication protocol // Physical communication protocol
StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol); StrCpy(st->UnderlayProtocol, sizeof(st->UnderlayProtocol), s->UnderlayProtocol);
// Protocol details
StrCpy(st->ProtocolDetails, sizeof(st->ProtocolDetails), s->ProtocolDetails);
Trim(st->ProtocolDetails);
// UDP acceleration function // UDP acceleration function
st->IsUdpAccelerationEnabled = s->UseUdpAcceleration; st->IsUdpAccelerationEnabled = s->UseUdpAcceleration;
st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration; st->IsUsingUdpAcceleration = s->IsUsingUdpAcceleration;
if (s->IpcSessionShared != NULL && IsEmptyStr(s->IpcSessionShared->ProtocolDetails) == false)
{
char tmp[256];
StrCpy(tmp, sizeof(tmp), s->IpcSessionShared->ProtocolDetails);
Trim(tmp);
StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), " ");
StrCat(st->ProtocolDetails, sizeof(st->ProtocolDetails), tmp);
st->IsUdpAccelerationEnabled = s->IpcSessionShared->EnableUdpAccel;
st->IsUsingUdpAcceleration = s->IpcSessionShared->UsingUdpAccel;
}
// Session key // Session key
Copy(st->SessionKey, s->SessionKey, SHA1_SIZE); Copy(st->SessionKey, s->SessionKey, SHA1_SIZE);
// Policy // Policy
@ -9299,6 +9350,12 @@ void CiInitConfiguration(CLIENT *c)
c->Config.UseKeepConnect = false; // Don't use the connection maintenance function by default in the Client c->Config.UseKeepConnect = false; // Don't use the connection maintenance function by default in the Client
// Eraser // Eraser
c->Eraser = NewEraser(c->Logger, 0); c->Eraser = NewEraser(c->Logger, 0);
#ifdef OS_WIN32
c->Config.DisableRpcDynamicPortListener = false;
#else // OS_WIN32
c->Config.DisableRpcDynamicPortListener = true;
#endif // OS_WIN32
} }
else else
{ {
@ -9445,6 +9502,21 @@ void CiLoadClientConfig(CLIENT_CONFIG *c, FOLDER *f)
c->AllowRemoteConfig = CfgGetBool(f, "AllowRemoteConfig"); c->AllowRemoteConfig = CfgGetBool(f, "AllowRemoteConfig");
c->KeepConnectInterval = MAKESURE(CfgGetInt(f, "KeepConnectInterval"), KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX); c->KeepConnectInterval = MAKESURE(CfgGetInt(f, "KeepConnectInterval"), KEEP_INTERVAL_MIN, KEEP_INTERVAL_MAX);
c->NoChangeWcmNetworkSettingOnWindows8 = CfgGetBool(f, "NoChangeWcmNetworkSettingOnWindows8"); c->NoChangeWcmNetworkSettingOnWindows8 = CfgGetBool(f, "NoChangeWcmNetworkSettingOnWindows8");
c->EnableTunnelCrackProtect = CfgGetBool(f, "EnableTunnelCrackProtect");
if (CfgIsItem(f, "DisableRpcDynamicPortListener"))
{
c->DisableRpcDynamicPortListener = CfgGetBool(f, "DisableRpcDynamicPortListener");
}
else
{
#ifdef OS_WIN32
c->DisableRpcDynamicPortListener = false;
#else // OS_WIN32
c->DisableRpcDynamicPortListener = true;
#endif // OS_WIN32
}
} }
// Read the client authentication data // Read the client authentication data
@ -9997,6 +10069,8 @@ void CiWriteClientConfig(FOLDER *cc, CLIENT_CONFIG *config)
CfgAddBool(cc, "AllowRemoteConfig", config->AllowRemoteConfig); CfgAddBool(cc, "AllowRemoteConfig", config->AllowRemoteConfig);
CfgAddInt(cc, "KeepConnectInterval", config->KeepConnectInterval); CfgAddInt(cc, "KeepConnectInterval", config->KeepConnectInterval);
CfgAddBool(cc, "NoChangeWcmNetworkSettingOnWindows8", config->NoChangeWcmNetworkSettingOnWindows8); CfgAddBool(cc, "NoChangeWcmNetworkSettingOnWindows8", config->NoChangeWcmNetworkSettingOnWindows8);
CfgAddBool(cc, "DisableRpcDynamicPortListener", config->DisableRpcDynamicPortListener);
CfgAddBool(cc, "EnableTunnelCrackProtect", config->EnableTunnelCrackProtect);
} }
// Write the client authentication data // Write the client authentication data

@ -186,6 +186,8 @@ struct CLIENT_CONFIG
UINT KeepConnectProtocol; // Protocol UINT KeepConnectProtocol; // Protocol
UINT KeepConnectInterval; // Interval UINT KeepConnectInterval; // Interval
bool NoChangeWcmNetworkSettingOnWindows8; // Don't change the WCM network settings on Windows 8 bool NoChangeWcmNetworkSettingOnWindows8; // Don't change the WCM network settings on Windows 8
bool DisableRpcDynamicPortListener;
bool EnableTunnelCrackProtect;
}; };
// Version acquisition // Version acquisition
@ -433,6 +435,7 @@ struct RPC_CLIENT_GET_CONNECTION_STATUS
bool UseCompress; // Use of compression bool UseCompress; // Use of compression
bool IsRUDPSession; // R-UDP session bool IsRUDPSession; // R-UDP session
char UnderlayProtocol[64]; // Physical communication protocol char UnderlayProtocol[64]; // Physical communication protocol
char ProtocolDetails[256]; // Protocol Details
bool IsUdpAccelerationEnabled; // The UDP acceleration is enabled bool IsUdpAccelerationEnabled; // The UDP acceleration is enabled
bool IsUsingUdpAcceleration; // Using the UDP acceleration function bool IsUsingUdpAcceleration; // Using the UDP acceleration function
char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name char SessionName[MAX_SESSION_NAME_LEN + 1]; // Session name

@ -196,6 +196,8 @@ void CheckNetworkAcceptThread(THREAD *thread, void *param)
Disconnect(s); Disconnect(s);
ReleaseSock(s); ReleaseSock(s);
Free(c);
} }
@ -239,15 +241,16 @@ void CheckNetworkListenThread(THREAD *thread, void *param)
} }
else else
{ {
CHECK_NETWORK_2 c; CHECK_NETWORK_2 *c;
THREAD *t; THREAD *t;
Zero(&c, sizeof(c)); Zero(&c, sizeof(c));
c.s = new_sock; c = ZeroMalloc(sizeof(CHECK_NETWORK_2));
c.k = pri; c->s = new_sock;
c.x = x; c->k = pri;
c->x = x;
t = NewThread(CheckNetworkAcceptThread, &c); t = NewThread(CheckNetworkAcceptThread, c);
Insert(o, t); Insert(o, t);
} }
} }
@ -14494,6 +14497,12 @@ void CmdPrintStatusToListViewEx(CT *ct, RPC_CLIENT_GET_CONNECTION_STATUS *s, boo
CtInsert(ct, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp); CtInsert(ct, _UU("CM_ST_UNDERLAY_PROTOCOL"), tmp);
} }
if (IsEmptyStr(s->ProtocolDetails) == false)
{
StrToUni(tmp, sizeof(tmp), s->ProtocolDetails);
CtInsert(ct, _UU("CM_ST_PROTOCOL_DETAILS"), tmp);
}
CtInsert(ct, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); CtInsert(ct, _UU("CM_ST_UDP_ACCEL_ENABLED"), (s->IsUdpAccelerationEnabled ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
CtInsert(ct, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO"))); CtInsert(ct, _UU("CM_ST_UDP_ACCEL_USING"), (s->IsUsingUdpAcceleration ? _UU("CM_ST_YES") : _UU("CM_ST_NO")));
@ -14780,55 +14789,6 @@ bool StrToPassOrDiscard(char *str)
return false; return false;
} }
// Convert the string to the protocol
UINT StrToProtocol(char *str)
{
if (IsEmptyStr(str))
{
return 0;
}
if (StartWith("ip", str))
{
return 0;
}
else if (StartWith("tcp", str))
{
return IP_PROTO_TCP;
}
else if (StartWith("udp", str))
{
return IP_PROTO_UDP;
}
else if (StartWith("icmpv4", str))
{
return IP_PROTO_ICMPV4;
}
else if (StartWith("icmpv6", str))
{
return IP_PROTO_ICMPV6;
}
if (ToInt(str) == 0)
{
if (StrCmpi(str, "0") == 0)
{
return 0;
}
else
{
return INFINITE;
}
}
if (ToInt(str) >= 256)
{
return INFINITE;
}
return ToInt(str);
}
// Check the protocol name // Check the protocol name
bool CmdEvalProtocol(CONSOLE *c, wchar_t *str, void *param) bool CmdEvalProtocol(CONSOLE *c, wchar_t *str, void *param)
{ {
@ -15029,7 +14989,7 @@ bool ParseTcpState(char *src, bool *check_tcp_state, bool *established)
if (IsEmptyStr(src) == false) if (IsEmptyStr(src) == false)
{ {
if (StartWith("Established", src) == 0) if (StartWith("Established", src))
{ {
if(ok != false) if(ok != false)
{ {
@ -15037,7 +14997,7 @@ bool ParseTcpState(char *src, bool *check_tcp_state, bool *established)
*established = true; *established = true;
} }
} }
else if (StartWith("Unestablished", src) == 0) else if (StartWith("Unestablished", src))
{ {
if(ok != false) if(ok != false)
{ {
@ -21663,6 +21623,9 @@ UINT PsLicenseAdd(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
FreeParamValueList(o); FreeParamValueList(o);
c->Write(c, _UU("SM_LICENSE_WARNING"));
c->Write(c, L"\n");
return 0; return 0;
} }
@ -23408,7 +23371,7 @@ void CmdPrintAbout(CONSOLE *c)
GetExeName(exe, sizeof(exe)); GetExeName(exe, sizeof(exe));
UniFormat(tmp, sizeof(tmp), _UU("CMD_VPNCMD_ABOUT"), UniFormat(tmp, sizeof(tmp), _UU("CMD_VPNCMD_ABOUT"),
cedar->VerString, cedar->BuildInfo); cedar->VerString, cedar->BuildInfo, BUILD_DATE_Y);
c->Write(c, tmp); c->Write(c, tmp);

@ -356,7 +356,6 @@ void CmdPrintStatusToListViewEx(CT *ct, RPC_CLIENT_GET_CONNECTION_STATUS *s, boo
bool CmdEvalPassOrDiscard(CONSOLE *c, wchar_t *str, void *param); bool CmdEvalPassOrDiscard(CONSOLE *c, wchar_t *str, void *param);
bool StrToPassOrDiscard(char *str); bool StrToPassOrDiscard(char *str);
bool CmdEvalProtocol(CONSOLE *c, wchar_t *str, void *param); bool CmdEvalProtocol(CONSOLE *c, wchar_t *str, void *param);
UINT StrToProtocol(char *str);
bool CmdEvalPortRange(CONSOLE *c, wchar_t *str, void *param); bool CmdEvalPortRange(CONSOLE *c, wchar_t *str, void *param);
bool ParsePortRange(char *str, UINT *start, UINT *end); bool ParsePortRange(char *str, UINT *start, UINT *end);
wchar_t *GetAuthTypeStr(UINT id); wchar_t *GetAuthTypeStr(UINT id);

@ -1267,6 +1267,8 @@ void ConnectionSend(CONNECTION *c, UINT64 now)
s->TotalSendSizeReal += b->Size; s->TotalSendSizeReal += b->Size;
c->CurrentSendQueueSize -= b->Size; c->CurrentSendQueueSize -= b->Size;
Free(new_buf);
} }
FreeBlock(b); FreeBlock(b);
@ -1707,7 +1709,7 @@ void ConnectionReceive(CONNECTION *c, CANCEL *c1, CANCEL *c2)
num = LIST_NUM(tcp->TcpSockList); num = LIST_NUM(tcp->TcpSockList);
if (num >= s->MaxConnection) if (num >= s->MaxConnection)
{ {
TCPSOCK *ts; TCPSOCK *ts = NULL;
for (i = 0;i < num;i++) for (i = 0;i < num;i++)
{ {
ts = LIST_DATA(tcp->TcpSockList, i); ts = LIST_DATA(tcp->TcpSockList, i);
@ -1720,6 +1722,8 @@ void ConnectionReceive(CONNECTION *c, CANCEL *c1, CANCEL *c2)
c2s++; c2s++;
} }
} }
if (ts != NULL)
{
if (s2c == 0 || c2s == 0) if (s2c == 0 || c2s == 0)
{ {
// Disconnect the last socket // Disconnect the last socket
@ -1728,6 +1732,7 @@ void ConnectionReceive(CONNECTION *c, CANCEL *c1, CANCEL *c2)
} }
} }
} }
}
UnlockList(tcp->TcpSockList); UnlockList(tcp->TcpSockList);
} }
@ -1861,6 +1866,18 @@ void ConnectionReceive(CONNECTION *c, CANCEL *c1, CANCEL *c2)
{ {
TUBE *t = sock->BulkRecvTube; TUBE *t = sock->BulkRecvTube;
//for testing purpose
//if (sock->test_tmp1 == 0) sock->test_tmp1 = now;
//if ((sock->test_tmp1 + 5000ULL) <= now)
//{
// // bugbug
// if (c->ServerMode == false)
// {
// WHERE;
// Disconnect(sock);
// }
//}
if (s->EnableBulkOnRUDP) if (s->EnableBulkOnRUDP)
{ {
// R-UDP bulk transfer data reception // R-UDP bulk transfer data reception
@ -2789,6 +2806,8 @@ BLOCK *NewBlock(void *data, UINT size, int compress)
b = MallocFast(sizeof(BLOCK)); b = MallocFast(sizeof(BLOCK));
b->RawFlagRetUdpAccel = 0;
b->IsFlooding = false; b->IsFlooding = false;
b->PriorityQoS = b->Ttl = b->Param1 = 0; b->PriorityQoS = b->Ttl = b->Param1 = 0;
@ -3121,8 +3140,8 @@ void ConnectionAccept(CONNECTION *c)
SetWantToUseCipher(s, c->Cedar->CipherList); SetWantToUseCipher(s, c->Cedar->CipherList);
} }
x = CloneX(c->Cedar->ServerX); x = CloneXFast(c->Cedar->ServerX);
k = CloneK(c->Cedar->ServerK); k = CloneKFast(c->Cedar->ServerK);
} }
Unlock(c->Cedar->lock); Unlock(c->Cedar->lock);
@ -3552,6 +3571,7 @@ CONNECTION *NewServerConnection(CEDAR *cedar, SOCK *s, THREAD *t)
{ {
AddRef(c->FirstSock->ref); AddRef(c->FirstSock->ref);
Copy(&c->ClientIp, &s->RemoteIP, sizeof(IP)); Copy(&c->ClientIp, &s->RemoteIP, sizeof(IP));
c->ClientPort = s->RemotePort;
StrCpy(c->ClientHostname, sizeof(c->ClientHostname), s->RemoteHostname); StrCpy(c->ClientHostname, sizeof(c->ClientHostname), s->RemoteHostname);
} }
c->Tcp = ZeroMalloc(sizeof(TCP)); c->Tcp = ZeroMalloc(sizeof(TCP));
@ -3571,7 +3591,7 @@ CONNECTION *NewServerConnection(CEDAR *cedar, SOCK *s, THREAD *t)
if (s != NULL && s->RemoteX != NULL) if (s != NULL && s->RemoteX != NULL)
{ {
c->ServerX = CloneX(s->RemoteX); c->ServerX = CloneXFast(s->RemoteX);
} }
if (s != NULL && s->Type == SOCK_INPROC) if (s != NULL && s->Type == SOCK_INPROC)

@ -252,6 +252,7 @@ struct BLOCK
UINT Ttl; // TTL value (Used only in ICMP NAT of Virtual.c) UINT Ttl; // TTL value (Used only in ICMP NAT of Virtual.c)
UINT Param1; // Parameter 1 UINT Param1; // Parameter 1
bool IsFlooding; // Is flooding packet bool IsFlooding; // Is flooding packet
UCHAR RawFlagRetUdpAccel; // Raw flag returned by UDP accel
}; };
// Connection structure // Connection structure
@ -299,12 +300,14 @@ struct CONNECTION
char *CipherName; // Encryption algorithm name char *CipherName; // Encryption algorithm name
UINT64 ConnectedTick; // Time it is connected UINT64 ConnectedTick; // Time it is connected
IP ClientIp; // Client IP address IP ClientIp; // Client IP address
UINT ClientPort; // Client Port number
char ClientHostname[MAX_HOST_NAME_LEN + 1]; // Client host name char ClientHostname[MAX_HOST_NAME_LEN + 1]; // Client host name
UINT Type; // Type UINT Type; // Type
bool DontUseTls1; // Do not use TLS 1.0 bool DontUseTls1; // Do not use TLS 1.0
void *hWndForUI; // Parent window void *hWndForUI; // Parent window
bool IsInProc; // In-process bool IsInProc; // In-process
char InProcPrefix[64]; // Prefix char InProcPrefix[64]; // Prefix
UINT InProcLayer; // InProc layer
UINT AdditionalConnectionFailedCounter; // Additional connection failure counter UINT AdditionalConnectionFailedCounter; // Additional connection failure counter
UINT64 LastCounterResetTick; // Time the counter was reset finally UINT64 LastCounterResetTick; // Time the counter was reset finally
bool WasSstp; // Processed the SSTP bool WasSstp; // Processed the SSTP
@ -314,6 +317,9 @@ struct CONNECTION
UINT LastPacketQueueSize; // The last queue size of packets UINT LastPacketQueueSize; // The last queue size of packets
UINT LastRecvFifoTotalSize; // The last RecvFifo total size UINT LastRecvFifoTotalSize; // The last RecvFifo total size
UINT LastRecvBlocksNum; // The last ReceivedBlocks num UINT LastRecvBlocksNum; // The last ReceivedBlocks num
bool IsJsonRpc; // Is JSON-RPC
bool JsonRpcAuthed; // JSON-RPC Authed
LISTENER *Listener; // Listener ref
}; };

@ -134,6 +134,9 @@ void DCGetStatus(DDNS_CLIENT *c, DDNS_CLIENT_STATUS *st)
Copy(&st->InternetSetting, &c->InternetSetting, sizeof(INTERNET_SETTING)); Copy(&st->InternetSetting, &c->InternetSetting, sizeof(INTERNET_SETTING));
} }
Unlock(c->Lock); Unlock(c->Lock);
UniStrCpy(st->ErrStr_IPv4, sizeof(st->ErrStr_IPv4), _E(st->Err_IPv4));
UniStrCpy(st->ErrStr_IPv6, sizeof(st->ErrStr_IPv6), _E(st->Err_IPv6));
} }
// Set the Internet settings // Set the Internet settings
@ -638,6 +641,7 @@ UINT DCRegister(DDNS_CLIENT *c, bool ipv6, DDNS_REGISTER_PARAM *p, char *replace
} }
use_https = true;
Format(url2, sizeof(url2), "%s?v=%I64u", url, Rand64()); Format(url2, sizeof(url2), "%s?v=%I64u", url, Rand64());
Format(url3, sizeof(url3), url2, key_hash_str[2], key_hash_str[3]); Format(url3, sizeof(url3), url2, key_hash_str[2], key_hash_str[3]);

@ -110,7 +110,11 @@
"439BAFA75A6EE5671FC9F9A02D34FF29881761A0" \ "439BAFA75A6EE5671FC9F9A02D34FF29881761A0" \
"EFAC5FA0CDD14E0F864EED58A73C35D7E33B62F3" \ "EFAC5FA0CDD14E0F864EED58A73C35D7E33B62F3" \
"74DF99D4B1B5F0488A388B50D347D26013DC67A5" \ "74DF99D4B1B5F0488A388B50D347D26013DC67A5" \
"6EBB39AFCA8C900635CFC11218CF293A612457E4" "6EBB39AFCA8C900635CFC11218CF293A612457E4" \
"05A9386C5E2B233F7BAB2479620EAAA2793709ED" \
"A811C64BB715351E36B6C1E022648D8BE0ACD128" \
"BD264DB3B0B1B3ABA0AF3074AA574ED1EF3B42D7" \
"9AB61D691536645DD55A8730FC6D2CDF33C8C73F"
#define DDNS_SNI_VER_STRING "DDNS" #define DDNS_SNI_VER_STRING "DDNS"
@ -135,7 +139,7 @@
#define DDNS_URL2_V4_ALT "http://get-my-ip.ddns.uxcom.jp/ddns/getmyip.ashx" #define DDNS_URL2_V4_ALT "http://get-my-ip.ddns.uxcom.jp/ddns/getmyip.ashx"
#define DDNS_URL2_V6_ALT "http://get-my-ip-v6.ddns.uxcom.jp/ddns/getmyip.ashx" #define DDNS_URL2_V6_ALT "http://get-my-ip-v6.ddns.uxcom.jp/ddns/getmyip.ashx"
#define DDNS_RPC_MAX_RECV_SIZE DYN32(DDNS_RPC_MAX_RECV_SIZE, (128 * 1024 * 1024)) #define DDNS_RPC_MAX_RECV_SIZE DYN32(DDNS_RPC_MAX_RECV_SIZE, (38 * 1024 * 1024))
// Connection Timeout // Connection Timeout
#define DDNS_CONNECT_TIMEOUT DYN32(DDNS_CONNECT_TIMEOUT, (15 * 1000)) #define DDNS_CONNECT_TIMEOUT DYN32(DDNS_CONNECT_TIMEOUT, (15 * 1000))
@ -208,6 +212,8 @@ struct DDNS_REGISTER_PARAM
struct DDNS_CLIENT_STATUS struct DDNS_CLIENT_STATUS
{ {
UINT Err_IPv4, Err_IPv6; // Last error UINT Err_IPv4, Err_IPv6; // Last error
wchar_t ErrStr_IPv4[MAX_SIZE];
wchar_t ErrStr_IPv6[MAX_SIZE];
char CurrentHostName[DDNS_MAX_HOSTNAME + 1]; // Current host name char CurrentHostName[DDNS_MAX_HOSTNAME + 1]; // Current host name
char CurrentFqdn[MAX_SIZE]; // Current FQDN char CurrentFqdn[MAX_SIZE]; // Current FQDN
char DnsSuffix[MAX_SIZE]; // DNS suffix char DnsSuffix[MAX_SIZE]; // DNS suffix

@ -662,6 +662,7 @@ void OutRpcEnumDevice(PACK *p, RPC_ENUM_DEVICE *t)
PackAddInt(p, "NumItem", t->NumItem); PackAddInt(p, "NumItem", t->NumItem);
PackSetCurrentJsonGroupName(p, "DeviceList");
for (i = 0;i < t->NumItem;i++) for (i = 0;i < t->NumItem;i++)
{ {
RPC_ENUM_DEVICE_ITEM *d = &t->Items[i]; RPC_ENUM_DEVICE_ITEM *d = &t->Items[i];
@ -669,6 +670,7 @@ void OutRpcEnumDevice(PACK *p, RPC_ENUM_DEVICE *t)
PackAddStrEx(p, "DeviceName", d->DeviceName, i, t->NumItem); PackAddStrEx(p, "DeviceName", d->DeviceName, i, t->NumItem);
PackAddBoolEx(p, "Active", d->Active, i, t->NumItem); PackAddBoolEx(p, "Active", d->Active, i, t->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
PackAddBool(p, "IsLicenseSupported", t->IsLicenseSupported); PackAddBool(p, "IsLicenseSupported", t->IsLicenseSupported);
} }
@ -709,7 +711,7 @@ void OutRpcElLicenseStatus(PACK *p, RPC_EL_LICENSE_STATUS *t)
PackAddBool(p, "Valid", t->Valid); PackAddBool(p, "Valid", t->Valid);
PackAddInt64(p, "SystemId", t->SystemId); PackAddInt64(p, "SystemId", t->SystemId);
PackAddInt64(p, "SystemExpires", t->SystemExpires); PackAddTime64(p, "SystemExpires", t->SystemExpires);
} }
// Listener thread // Listener thread

@ -159,7 +159,7 @@ UINT num_admin_options = sizeof(admin_options) / sizeof(ADMIN_OPTION);
// Create an EAP client for the specified Virtual Hub // Create an EAP client for the specified Virtual Hub
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username) EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str)
{ {
HUB *hub = NULL; HUB *hub = NULL;
EAP_CLIENT *ret = NULL; EAP_CLIENT *ret = NULL;
@ -209,6 +209,11 @@ EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, ch
if (eap != NULL) if (eap != NULL)
{ {
if (IsEmptyStr(vpn_protocol_state_str) == false)
{
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), vpn_protocol_state_str);
}
if (use_peap == false) if (use_peap == false)
{ {
// EAP // EAP
@ -778,6 +783,8 @@ void HubOptionStructToData(RPC_ADMIN_OPTION *ao, HUB_OPTION *o, char *hub_name)
{ {
ADMIN_OPTION *a = LIST_DATA(aol, i); ADMIN_OPTION *a = LIST_DATA(aol, i);
UniStrCpy(a->Descrption, sizeof(a->Descrption), GetHubAdminOptionHelpString(a->Name));
Copy(&ao->Items[i], a, sizeof(ADMIN_OPTION)); Copy(&ao->Items[i], a, sizeof(ADMIN_OPTION));
Free(a); Free(a);
@ -1653,13 +1660,15 @@ void HubWatchDogThread(THREAD *t, void *param)
o2 = NewListFast(NULL); o2 = NewListFast(NULL);
// Send an ARP packet // Send an ARP packet
LockList(hub->IpTable); LockHashList(hub->MacHashTable);
{ {
num = LIST_NUM(hub->IpTable); num = LIST_NUM(hub->IpTable);
for (i = 0;i < LIST_NUM(hub->IpTable);i++) for (i = 0;i < LIST_NUM(hub->IpTable);i++)
{ {
IP_TABLE_ENTRY *e = LIST_DATA(hub->IpTable, i); IP_TABLE_ENTRY *e = LIST_DATA(hub->IpTable, i);
if (e == NULL) continue;
if ((e->UpdatedTime + (UINT64)(IP_TABLE_EXPIRE_TIME)) > Tick64()) if ((e->UpdatedTime + (UINT64)(IP_TABLE_EXPIRE_TIME)) > Tick64())
{ {
if (e->MacAddress[0] != 0xff || e->MacAddress[1] != 0xff || e->MacAddress[2] != 0xff || if (e->MacAddress[0] != 0xff || e->MacAddress[1] != 0xff || e->MacAddress[2] != 0xff ||
@ -1735,7 +1744,7 @@ void HubWatchDogThread(THREAD *t, void *param)
} }
} }
} }
UnlockList(hub->IpTable); UnlockHashList(hub->MacHashTable);
if ((LIST_NUM(o) + LIST_NUM(o2)) != 0) if ((LIST_NUM(o) + LIST_NUM(o2)) != 0)
{ {
@ -3899,6 +3908,7 @@ LABEL_TRY_AGAIN:
return true; return true;
} }
// VGS: Setting for embedding UA tag // VGS: Setting for embedding UA tag
void VgsSetEmbTag(bool b) void VgsSetEmbTag(bool b)
{ {
@ -4113,6 +4123,17 @@ void StorePacket(HUB *hub, SESSION *s, PKT *packet)
} }
} }
if (s != NULL)
{
if (s->EnableLightRecvFilter)
{
if (IsValidUnicastMacAddress(packet->MacAddressSrc))
{
s->LightRecvFilterMac = READ_UINT(packet->MacAddressSrc + 2);
}
}
}
// Lock the entire MAC address table // Lock the entire MAC address table
LockHashList(hub->MacHashTable); LockHashList(hub->MacHashTable);
{ {
@ -4782,6 +4803,18 @@ UPDATE_FDB:
Insert(hub->IpTable, e); Insert(hub->IpTable, e);
if (s->EnableLightRecvFilter)
{
if (s->LightRecvFilterIPv4_1 == 0)
{
s->LightRecvFilterIPv4_1 = uint_ip;
}
else
{
s->LightRecvFilterIPv4_2 = uint_ip;
}
}
if (0) if (0)
{ {
char ip_address[64]; char ip_address[64];
@ -5029,6 +5062,7 @@ DISCARD_UNICAST_PACKET:
{ {
// Flooding as a broadcast packet // Flooding as a broadcast packet
UINT current_tcp_queue_size = 0; UINT current_tcp_queue_size = 0;
UINT bcast_mac_dst = READ_UINT(packet->MacAddressDest + 2);
// Take a packet log // Take a packet log
if (s != NULL) if (s != NULL)
@ -5054,9 +5088,60 @@ DISCARD_UNICAST_PACKET:
{ {
bool delete_default_router_in_ra = false; bool delete_default_router_in_ra = false;
if (dest_session->Policy != NULL && dest_session->Policy->DHCPNoServer)
{
if (packet->TypeL3 == L3_IPV4 &&
packet->TypeL4 == L4_UDP &&
packet->TypeL7 == L7_DHCPV4 &&
(packet->DhcpOpCode == DHCP_DISCOVER || packet->DhcpOpCode == DHCP_REQUEST || packet->DhcpOpCode == DHCP_RELEASE || packet->DhcpOpCode == DHCP_INFORM))
{
discard = true;
goto L_SKIP_TO_DISCARD;
}
}
if (dest_session->EnableLightRecvFilter)
{
if (packet->BroadcastPacket == false &&
dest_session->LightRecvFilterMac != 0 &&
dest_session->LightRecvFilterMac != bcast_mac_dst)
{
discard = true;
goto L_SKIP_TO_DISCARD;
}
if (packet->BroadcastPacket &&
packet->TypeL3 == L3_ARPV4 &&
packet->L3.ARPv4Header->HardwareSize == 6 &&
Endian16(packet->L3.ARPv4Header->HardwareType) == ARP_HARDWARE_TYPE_ETHERNET &&
packet->L3.ARPv4Header->ProtocolSize == 4 &&
Endian16(packet->L3.ARPv4Header->ProtocolType) == MAC_PROTO_IPV4)
{
if (Endian16(packet->L3.ARPv4Header->Operation) == ARP_OPERATION_REQUEST)
{
bool ok = false;
if (dest_session->LightRecvFilterIPv4_1 != 0)
if (dest_session->LightRecvFilterIPv4_1 == packet->L3.ARPv4Header->TargetIP)
ok = true;
if (dest_session->LightRecvFilterIPv4_2 != 0)
if (dest_session->LightRecvFilterIPv4_2 == packet->L3.ARPv4Header->TargetIP)
ok = true;
if (ok == false)
{
discard = true;
goto L_SKIP_TO_DISCARD;
}
}
}
}
if (dest_session->IsMonitorMode) if (dest_session->IsMonitorMode)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
if (dest_session->NormalClient) if (dest_session->NormalClient)
@ -5068,6 +5153,7 @@ DISCARD_UNICAST_PACKET:
{ {
// This is dormant session // This is dormant session
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
} }
@ -5083,6 +5169,7 @@ DISCARD_UNICAST_PACKET:
dest_session->Connection->Protocol == CONNECTION_TCP) dest_session->Connection->Protocol == CONNECTION_TCP)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
if (dest_session->LinkModeServer) if (dest_session->LinkModeServer)
@ -5090,6 +5177,7 @@ DISCARD_UNICAST_PACKET:
LINK *k = dest_session->Link; LINK *k = dest_session->Link;
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
} }
@ -5098,6 +5186,7 @@ DISCARD_UNICAST_PACKET:
packet->VlanId != dest_session->VLanId) packet->VlanId != dest_session->VLanId)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
if (dest_session->Policy->NoIPv6DefaultRouterInRA || if (dest_session->Policy->NoIPv6DefaultRouterInRA ||
@ -5121,6 +5210,7 @@ DISCARD_UNICAST_PACKET:
packet->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_ROUTER_ADVERTISEMENT)) packet->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_ROUTER_ADVERTISEMENT))
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
@ -5131,6 +5221,7 @@ DISCARD_UNICAST_PACKET:
packet->TypeL7 == L7_DHCPV4) packet->TypeL7 == L7_DHCPV4)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
@ -5141,6 +5232,7 @@ DISCARD_UNICAST_PACKET:
(Endian16(packet->L4.UDPHeader->DstPort) == 546 || Endian16(packet->L4.UDPHeader->DstPort) == 547)) (Endian16(packet->L4.UDPHeader->DstPort) == 546 || Endian16(packet->L4.UDPHeader->DstPort) == 547))
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
@ -5184,6 +5276,7 @@ DISCARD_UNICAST_PACKET:
if (packet->TypeL3 == L3_IPV4 || packet->TypeL3 == L3_ARPV4) if (packet->TypeL3 == L3_IPV4 || packet->TypeL3 == L3_ARPV4)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
if (dest_session->Policy->FilterIPv6) if (dest_session->Policy->FilterIPv6)
@ -5191,6 +5284,7 @@ DISCARD_UNICAST_PACKET:
if (packet->TypeL3 == L3_IPV6) if (packet->TypeL3 == L3_IPV6)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
if (dest_session->Policy->FilterNonIP) if (dest_session->Policy->FilterNonIP)
@ -5198,6 +5292,7 @@ DISCARD_UNICAST_PACKET:
if (packet->TypeL3 != L3_IPV4 && packet->TypeL3 != L3_ARPV4 && packet->TypeL3 != L3_IPV6) if (packet->TypeL3 != L3_IPV4 && packet->TypeL3 != L3_ARPV4 && packet->TypeL3 != L3_IPV6)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
@ -5211,6 +5306,7 @@ DISCARD_UNICAST_PACKET:
if (drop_arp_packet_privacy || packet->TypeL3 != L3_ARPV4) if (drop_arp_packet_privacy || packet->TypeL3 != L3_ARPV4)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
@ -5220,9 +5316,12 @@ DISCARD_UNICAST_PACKET:
memcmp(packet->MacAddressDest, s->Hub->HubMacAddr, 6) == 0) memcmp(packet->MacAddressDest, s->Hub->HubMacAddr, 6) == 0)
{ {
discard = true; discard = true;
goto L_SKIP_TO_DISCARD;
} }
} }
L_SKIP_TO_DISCARD:
if (discard == false && dest_pa != NULL) if (discard == false && dest_pa != NULL)
{ {
if (s == NULL || if (s == NULL ||
@ -5237,7 +5336,10 @@ DISCARD_UNICAST_PACKET:
{ {
PKT *pkt2 = ParsePacket(data, size); PKT *pkt2 = ParsePacket(data, size);
if (pkt2 != NULL)
{
DeleteIPv6DefaultRouterInRA(pkt2); DeleteIPv6DefaultRouterInRA(pkt2);
}
FreePacket(pkt2); FreePacket(pkt2);
} }
@ -5581,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 // Remove the default router specification from the IPv6 router advertisement
bool DeleteIPv6DefaultRouterInRA(PKT *p) bool DeleteIPv6DefaultRouterInRA(PKT *p)
{ {
if (p == NULL)
{
return false;
}
if (p->TypeL3 == L3_IPV6 && p->TypeL4 == L4_ICMPV6 && if (p->TypeL3 == L3_IPV6 && p->TypeL4 == L4_ICMPV6 &&
(p->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_ROUTER_ADVERTISEMENT)) (p->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_ROUTER_ADVERTISEMENT))
{ {
@ -5892,6 +5999,21 @@ bool StorePacketFilterByPolicy(SESSION *s, PKT *p)
UINTToIP(&ip, ip_uint); UINTToIP(&ip, ip_uint);
Copy(&t.Ip, &ip, sizeof(IP)); Copy(&t.Ip, &ip, sizeof(IP));
if (mac_table->Session != NULL)
{
if (mac_table->Session->EnableLightRecvFilter)
{
if (mac_table->Session->LightRecvFilterIPv4_1 == 0)
{
mac_table->Session->LightRecvFilterIPv4_1 = ip_uint;
}
else
{
mac_table->Session->LightRecvFilterIPv4_2 = ip_uint;
}
}
}
e = Search(hub->IpTable, &t); e = Search(hub->IpTable, &t);
if (e == NULL) if (e == NULL)
{ {

@ -306,58 +306,6 @@ struct LOOP_LIST
SESSION **Session; SESSION **Session;
}; };
// Access list
struct ACCESS
{
// IPv4
UINT Id; // ID
wchar_t Note[MAX_ACCESSLIST_NOTE_LEN + 1]; // Note
// --- Please add items to the bottom of here for enhancements ---
bool Active; // Enable flag
UINT Priority; // Priority
bool Discard; // Discard flag
UINT SrcIpAddress; // Source IP address
UINT SrcSubnetMask; // Source subnet mask
UINT DestIpAddress; // Destination IP address
UINT DestSubnetMask; // Destination subnet mask
UINT Protocol; // Protocol
UINT SrcPortStart; // Source port number starting point
UINT SrcPortEnd; // Source port number end point
UINT DestPortStart; // Destination port number starting point
UINT DestPortEnd; // Destination port number end point
UINT64 SrcUsernameHash; // Source user name hash
bool IsSrcUsernameIncludeOrExclude; // The source user name is formed as the "include:" or "exclude:"
char SrcUsername[MAX_USERNAME_LEN + 1];
bool IsDestUsernameIncludeOrExclude; // The destination user name is formed as "include:" or "exclude:"
UINT64 DestUsernameHash; // Destination user name hash
char DestUsername[MAX_USERNAME_LEN + 1];
bool CheckSrcMac; // Presence of a source MAC address setting
UCHAR SrcMacAddress[6]; // Source MAC address
UCHAR SrcMacMask[6]; // Source MAC address mask
bool CheckDstMac; // Whether the setting of the destination MAC address exists
UCHAR DstMacAddress[6]; // Destination MAC address
UCHAR DstMacMask[6]; // Destination MAC address mask
bool CheckTcpState; // The state of the TCP connection
bool Established; // Establieshed(TCP)
UINT Delay; // Delay
UINT Jitter; // Jitter
UINT Loss; // Packet loss
char RedirectUrl[MAX_REDIRECT_URL_LEN + 1]; // URL to redirect to
// IPv6
bool IsIPv6; // Whether it's an IPv6
IPV6_ADDR SrcIpAddress6; // The source IP address (IPv6)
IPV6_ADDR SrcSubnetMask6; // Source subnet mask (IPv6)
IPV6_ADDR DestIpAddress6; // Destination IP address (IPv6)
IPV6_ADDR DestSubnetMask6; // Destination subnet mask (IPv6)
// --- Please add items to the above of here for enhancements ---
// For management
UINT UniqueId; // Unique ID
};
// Ticket // Ticket
struct TICKET struct TICKET
{ {
@ -384,6 +332,7 @@ struct ADMIN_OPTION
{ {
char Name[MAX_ADMIN_OPTION_NAME_LEN + 1]; // Name char Name[MAX_ADMIN_OPTION_NAME_LEN + 1]; // Name
UINT Value; // Data UINT Value; // Data
wchar_t Descrption[MAX_SIZE]; // Descrption
}; };
// Certificate Revocation List entry // Certificate Revocation List entry
@ -432,6 +381,7 @@ struct HUB
char RadiusRealm[MAX_SIZE]; // Radius realm (optional) char RadiusRealm[MAX_SIZE]; // Radius realm (optional)
bool RadiusConvertAllMsChapv2AuthRequestToEap; // Convert all MS-CHAPv2 auth request to EAP bool RadiusConvertAllMsChapv2AuthRequestToEap; // Convert all MS-CHAPv2 auth request to EAP
bool RadiusUsePeapInsteadOfEap; // Use PEAP instead of 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 volatile bool Halt; // Halting flag
bool Offline; // Offline bool Offline; // Offline
bool BeingOffline; // Be Doing Offline bool BeingOffline; // Be Doing Offline
@ -634,7 +584,8 @@ void CalcTrafficDiff(TRAFFIC *diff, TRAFFIC *old, TRAFFIC *current);
bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now); bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now);
void VgsSetUserAgentValue(char *str); void VgsSetUserAgentValue(char *str);
void VgsSetEmbTag(bool b); void VgsSetEmbTag(bool b);
EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username); EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username, char *vpn_protocol_state_str);
#endif // HUB_H #endif // HUB_H

@ -381,6 +381,13 @@ void IPsecServerUdpPacketRecvProc(UDPLISTENER *u, LIST *packet_list)
ike->Now = now; ike->Now = now;
if (now >= ike->NextInfoMsgQuotaClearTick)
{
ike->NextInfoMsgQuotaClearTick = now + 1000ULL;
IkeInfoMsgQuotaDeleteAll(ike);
}
if (ipsec_disable == false) if (ipsec_disable == false)
{ {
{ {

@ -161,7 +161,7 @@ void EtherIPIpcConnectThread(THREAD *t, void *p)
&s->ClientIP, s->ClientPort, &s->ClientIP, s->ClientPort,
&s->ServerIP, s->ServerPort, &s->ServerIP, s->ServerPort,
tmp, tmp,
s->CryptName, true, mss, NULL); s->CryptName, true, mss, NULL, NULL, IPC_LAYER_2);
if (ipc != NULL) if (ipc != NULL)
{ {

@ -135,7 +135,10 @@ void ProcIKEPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
break; break;
case IKE_EXCHANGE_TYPE_AGGRESSIVE: // Aggressive mode case IKE_EXCHANGE_TYPE_AGGRESSIVE: // Aggressive mode
if (ike->Cedar->Server->DisableIPsecAggressiveMode == false)
{
ProcIkeAggressiveModePacketRecv(ike, p, header); ProcIkeAggressiveModePacketRecv(ike, p, header);
}
break; break;
case IKE_EXCHANGE_TYPE_QUICK: // Quick mode case IKE_EXCHANGE_TYPE_QUICK: // Quick mode
@ -156,6 +159,55 @@ void ProcIKEPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
} }
} }
IKE_INFOMSG_QUOTA_ENTRY *IkeInfoMsgQuotaGetEntry(IKE_SERVER *ike, IP *client_ip)
{
UINT i;
IKE_INFOMSG_QUOTA_ENTRY *new_entry = NULL;
if (ike == NULL || client_ip == NULL)
{
return NULL;
}
for (i = 0;i < LIST_NUM(ike->InfoMsgQuotaList);i++)
{
IKE_INFOMSG_QUOTA_ENTRY *q = LIST_DATA(ike->InfoMsgQuotaList, i);
if (CmpIpAddr(&q->ClientIp, client_ip) == 0)
{
return q;
}
}
if (LIST_NUM(ike->InfoMsgQuotaList) >= IKE_QUOTA_MAX_INFOMSG_ENTRY_COUNT)
{
return NULL;
}
new_entry = ZeroMalloc(sizeof(IKE_INFOMSG_QUOTA_ENTRY));
CopyIP(&new_entry->ClientIp, client_ip);
Add(ike->InfoMsgQuotaList, new_entry);
return new_entry;
}
void IkeInfoMsgQuotaDeleteAll(IKE_SERVER *ike)
{
UINT i;
if (ike == NULL)
{
return;
}
for (i = 0;i < LIST_NUM(ike->InfoMsgQuotaList);i++)
{
IKE_INFOMSG_QUOTA_ENTRY *q = LIST_DATA(ike->InfoMsgQuotaList, i);
Free(q);
}
DeleteAll(ike->InfoMsgQuotaList);
}
// Send a packet via IPsec // Send a packet via IPsec
void IPsecSendPacketByIPsecSa(IKE_SERVER *ike, IPSECSA *sa, UCHAR *data, UINT data_size, UCHAR protocol_id) void IPsecSendPacketByIPsecSa(IKE_SERVER *ike, IPSECSA *sa, UCHAR *data, UINT data_size, UCHAR protocol_id)
{ {
@ -545,36 +597,15 @@ void ProcIPsecEspPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
ipsec_sa = SearchClientToServerIPsecSaBySpi(ike, spi); ipsec_sa = SearchClientToServerIPsecSaBySpi(ike, spi);
if (ipsec_sa == NULL) if (ipsec_sa == NULL)
{ {
// Invalid SPI // Do nothing: see https://github.com/SoftEtherVPN/SoftEtherVPN/security/advisories/GHSA-j35p-p8pj-vqxq
UINT64 init_cookie = Rand64(); // RFC4303, in 3.4.2
UINT64 resp_cookie = 0; // If no valid Security Association exists for this packet, the receiver
IKE_CLIENT *c = NULL; // MUST discard the packet; this is an auditable event. The audit log
IKE_CLIENT t; // 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.
Copy(&t.ClientIP, &p->SrcIP, sizeof(IP)); //
t.ClientPort = p->SrcPort; // Thank you for phillibert, Amazon Web Services, Inc.
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);
return; return;
} }
@ -1334,6 +1365,7 @@ void SendInformationalExchangePacketEx(IKE_SERVER *ike, IKE_CLIENT *c, IKE_PACKE
BUF *tmp_buf; BUF *tmp_buf;
UCHAR hash[IKE_MAX_HASH_SIZE]; UCHAR hash[IKE_MAX_HASH_SIZE];
IKE_CRYPTO_PARAM cp; IKE_CRYPTO_PARAM cp;
IKE_INFOMSG_QUOTA_ENTRY *quota_entry;
bool plain = false; bool plain = false;
// Validate arguments // Validate arguments
if (ike == NULL || c == NULL || payload == NULL) if (ike == NULL || c == NULL || payload == NULL)
@ -1342,6 +1374,20 @@ void SendInformationalExchangePacketEx(IKE_SERVER *ike, IKE_CLIENT *c, IKE_PACKE
return; return;
} }
quota_entry = IkeInfoMsgQuotaGetEntry(ike, &c->ClientIP);
if (quota_entry == NULL)
{
IkeFreePayload(payload);
return;
}
quota_entry->Count++;
if (quota_entry->Count >= IKE_QUOTA_MAX_INFOMSG_SEND_PER_IP_PER_SEC)
{
IkeFreePayload(payload);
return;
}
sa = c->CurrentIkeSa; sa = c->CurrentIkeSa;
if (sa == NULL) if (sa == NULL)
{ {
@ -1417,13 +1463,13 @@ void SendInformationalExchangePacketEx(IKE_SERVER *ike, IKE_CLIENT *c, IKE_PACKE
IkeSendUdpPacket(ike, IKE_UDP_TYPE_ISAKMP, &c->ServerIP, c->ServerPort, IkeSendUdpPacket(ike, IKE_UDP_TYPE_ISAKMP, &c->ServerIP, c->ServerPort,
&c->ClientIP, c->ClientPort, &c->ClientIP, c->ClientPort,
ps_buf->Buf, ps_buf->Size); Clone(ps_buf->Buf, ps_buf->Size), ps_buf->Size);
#ifdef RAW_DEBUG #ifdef RAW_DEBUG
IkeDebugUdpSendRawPacket(ps); IkeDebugUdpSendRawPacket(ps);
#endif // RAW_DEBUG #endif // RAW_DEBUG
Free(ps_buf); FreeBuf(ps_buf);
IkeFree(ps); IkeFree(ps);
} }
@ -4055,9 +4101,9 @@ void IPsecSaSendPacket(IKE_SERVER *ike, IPSECSA *sa, IKE_PACKET *p)
IkeSendUdpPacket(ike, IKE_UDP_TYPE_ISAKMP, &sa->IkeClient->ServerIP, sa->IkeClient->ServerPort, IkeSendUdpPacket(ike, IKE_UDP_TYPE_ISAKMP, &sa->IkeClient->ServerIP, sa->IkeClient->ServerPort,
&sa->IkeClient->ClientIP, sa->IkeClient->ClientPort, &sa->IkeClient->ClientIP, sa->IkeClient->ClientPort,
buf->Buf, buf->Size); Clone(buf->Buf, buf->Size), buf->Size);
Free(buf); FreeBuf(buf);
} }
// Send a packet using the IKE SA // Send a packet using the IKE SA
@ -4115,9 +4161,9 @@ void IkeSaSendPacket(IKE_SERVER *ike, IKE_SA *sa, IKE_PACKET *p)
IkeSendUdpPacket(ike, IKE_UDP_TYPE_ISAKMP, &sa->IkeClient->ServerIP, sa->IkeClient->ServerPort, IkeSendUdpPacket(ike, IKE_UDP_TYPE_ISAKMP, &sa->IkeClient->ServerIP, sa->IkeClient->ServerPort,
&sa->IkeClient->ClientIP, sa->IkeClient->ClientPort, &sa->IkeClient->ClientIP, sa->IkeClient->ClientPort,
buf->Buf, buf->Size); Clone(buf->Buf, buf->Size), buf->Size);
Free(buf); FreeBuf(buf);
} }
// Send an UDP packet // Send an UDP packet
@ -5937,6 +5983,15 @@ void FreeIKEServer(IKE_SERVER *ike)
FreeIkeEngine(ike->Engine); FreeIkeEngine(ike->Engine);
for (i = 0;i < LIST_NUM(ike->InfoMsgQuotaList);i++)
{
IKE_INFOMSG_QUOTA_ENTRY *q = LIST_DATA(ike->InfoMsgQuotaList, i);
Free(q);
}
ReleaseList(ike->InfoMsgQuotaList);
Debug("FreeThreadList()...\n"); Debug("FreeThreadList()...\n");
FreeThreadList(ike->ThreadList); FreeThreadList(ike->ThreadList);
Debug("FreeThreadList() Done.\n"); Debug("FreeThreadList() Done.\n");
@ -5971,6 +6026,8 @@ IKE_SERVER *NewIKEServer(CEDAR *cedar, IPSEC_SERVER *ipsec)
ike->ClientList = NewList(CmpIkeClient); ike->ClientList = NewList(CmpIkeClient);
ike->InfoMsgQuotaList = NewList(NULL);
ike->Engine = NewIkeEngine(); ike->Engine = NewIkeEngine();
ike->ThreadList = NewThreadList(); ike->ThreadList = NewThreadList();

@ -148,6 +148,9 @@
#define IKE_QUOTA_MAX_NUM_CLIENTS 30000 // Limit number of IKE_CLIENT #define IKE_QUOTA_MAX_NUM_CLIENTS 30000 // Limit number of IKE_CLIENT
#define IKE_QUOTA_MAX_SA_PER_CLIENT 100 // The limit number of SA for each IKE_CLIENT #define IKE_QUOTA_MAX_SA_PER_CLIENT 100 // The limit number of SA for each IKE_CLIENT
#define IKE_QUOTA_MAX_INFOMSG_SEND_PER_IP_PER_SEC 20
#define IKE_QUOTA_MAX_INFOMSG_ENTRY_COUNT 100
// Time-out // Time-out
#define IKE_TIMEOUT_FOR_IKE_CLIENT 150000 // IKE_CLIENT non-communication disconnect time #define IKE_TIMEOUT_FOR_IKE_CLIENT 150000 // IKE_CLIENT non-communication disconnect time
#define IKE_TIMEOUT_FOR_IKE_CLIENT_FOR_NOT_ESTABLISHED 10000 // IKE_CLIENT non-communication disconnect time (connection incomplete) #define IKE_TIMEOUT_FOR_IKE_CLIENT_FOR_NOT_ESTABLISHED 10000 // IKE_CLIENT non-communication disconnect time (connection incomplete)
@ -346,6 +349,12 @@ struct IPSECSA
IKE_HASH *SKEYID_Hash; IKE_HASH *SKEYID_Hash;
}; };
struct IKE_INFOMSG_QUOTA_ENTRY
{
IP ClientIp;
UINT Count;
};
// IKE server // IKE server
struct IKE_SERVER struct IKE_SERVER
{ {
@ -360,6 +369,8 @@ struct IKE_SERVER
LIST *IkeSaList; // SA list LIST *IkeSaList; // SA list
LIST *IPsecSaList; // IPsec SA list LIST *IPsecSaList; // IPsec SA list
LIST *ThreadList; // L2TP thread list LIST *ThreadList; // L2TP thread list
LIST *InfoMsgQuotaList; // Information Message Quota List
UINT64 NextInfoMsgQuotaClearTick;
bool StateHasChanged; // Flag whether the state has changed bool StateHasChanged; // Flag whether the state has changed
UINT CurrentIkeSaId, CurrentIPsecSaId, CurrentIkeClientId, CurrentEtherId; // Serial number ID UINT CurrentIkeSaId, CurrentIPsecSaId, CurrentIkeClientId, CurrentEtherId; // Serial number ID
@ -463,5 +474,8 @@ void ProcL2TPv3PacketRecv(IKE_SERVER *ike, IKE_CLIENT *c, UCHAR *data, UINT data
IKE_SA *SearchIkeSaByCookie(IKE_SERVER *ike, UINT64 init_cookie, UINT64 resp_cookie); IKE_SA *SearchIkeSaByCookie(IKE_SERVER *ike, UINT64 init_cookie, UINT64 resp_cookie);
IKE_INFOMSG_QUOTA_ENTRY *IkeInfoMsgQuotaGetEntry(IKE_SERVER *ike, IP *client_ip);
void IkeInfoMsgQuotaDeleteAll(IKE_SERVER *ike);
#endif // IPSEC_IKE_H #endif // IPSEC_IKE_H

@ -179,6 +179,12 @@ IPC_ASYNC *NewIPCAsync(CEDAR *cedar, IPC_PARAM *param, SOCK_EVENT *sock_event)
Copy(&a->Param, param, sizeof(IPC_PARAM)); Copy(&a->Param, param, sizeof(IPC_PARAM));
if (param->ClientCertificate != NULL)
{
// Client certificate must be copied for async processing
a->Param.ClientCertificate = CloneX(param->ClientCertificate);
}
if (sock_event != NULL) if (sock_event != NULL)
{ {
a->SockEvent = sock_event; a->SockEvent = sock_event;
@ -297,6 +303,12 @@ void FreeIPCAsync(IPC_ASYNC *a)
ReleaseCedar(a->Cedar); ReleaseCedar(a->Cedar);
ReleaseTube(a->TubeForDisconnect); ReleaseTube(a->TubeForDisconnect);
if (a->Param.ClientCertificate != NULL)
{
FreeX(a->Param.ClientCertificate);
}
Free(a); Free(a);
} }
@ -314,7 +326,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
param->UserName, param->Password, error_code, &param->ClientIp, param->UserName, param->Password, error_code, &param->ClientIp,
param->ClientPort, &param->ServerIp, param->ServerPort, param->ClientPort, &param->ServerIp, param->ServerPort,
param->ClientHostname, param->CryptName, param->ClientHostname, param->CryptName,
param->BridgeMode, param->Mss, NULL); param->BridgeMode, param->Mss, NULL, param->ClientCertificate, param->Layer);
return ipc; return ipc;
} }
@ -323,7 +335,8 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
char *client_hostname, char *crypt_name, char *client_hostname, char *crypt_name,
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client) bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
UINT layer)
{ {
IPC *ipc; IPC *ipc;
UINT dummy_int = 0; UINT dummy_int = 0;
@ -338,6 +351,7 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
NODE_INFO info; NODE_INFO info;
BUF *b; BUF *b;
UCHAR mschap_v2_server_response_20[20]; UCHAR mschap_v2_server_response_20[20];
UINT64 u64;
// Validate arguments // Validate arguments
if (cedar == NULL || username == NULL || password == NULL || client_hostname == NULL) if (cedar == NULL || username == NULL || password == NULL || client_hostname == NULL)
{ {
@ -371,6 +385,12 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
ipc->Cedar = cedar; ipc->Cedar = cedar;
AddRef(cedar->ref); AddRef(cedar->ref);
ipc->Layer = layer;
if (ipc->Layer == 0)
{
ipc->Layer = IPC_LAYER_2;
}
ipc->FlushList = NewTubeFlushList(); ipc->FlushList = NewTubeFlushList();
StrCpy(ipc->ClientHostname, sizeof(ipc->ClientHostname), client_hostname); StrCpy(ipc->ClientHostname, sizeof(ipc->ClientHostname), client_hostname);
@ -416,7 +436,14 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
FreePack(p); FreePack(p);
// Upload the authentication data // Upload the authentication data
if (client_certificate != NULL)
{
p = PackLoginWithOpenVPNCertificate(hubname, username, client_certificate);
}
else
{
p = PackLoginWithPlainPassword(hubname, username, password); p = PackLoginWithPlainPassword(hubname, username, password);
}
PackAddStr(p, "hello", client_name); PackAddStr(p, "hello", client_name);
PackAddInt(p, "client_ver", cedar->Version); PackAddInt(p, "client_ver", cedar->Version);
PackAddInt(p, "client_build", cedar->Build); PackAddInt(p, "client_build", cedar->Build);
@ -451,6 +478,7 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
PackAddStr(p, "inproc_postfix", postfix); PackAddStr(p, "inproc_postfix", postfix);
PackAddStr(p, "inproc_cryptname", crypt_name); PackAddStr(p, "inproc_cryptname", crypt_name);
PackAddInt(p, "inproc_layer", ipc->Layer);
// Node information // Node information
Zero(&info, sizeof(info)); Zero(&info, sizeof(info));
@ -532,6 +560,10 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
Debug("IPC: Session = %s, Connection = %s, Mac = %s\n", ipc->SessionName, ipc->ConnectionName, macstr); Debug("IPC: Session = %s, Connection = %s, Mac = %s\n", ipc->SessionName, ipc->ConnectionName, macstr);
u64 = PackGetInt64(p, "IpcSessionSharedBuffer");
ipc->IpcSessionSharedBuffer = (SHARED_BUFFER *)u64;
ipc->IpcSessionShared = ipc->IpcSessionSharedBuffer->Data;
FreePack(p); FreePack(p);
ReleaseSock(a); ReleaseSock(a);
@ -666,6 +698,8 @@ void FreeIPC(IPC *ipc)
ReleaseQueue(ipc->IPv4RecviedQueue); ReleaseQueue(ipc->IPv4RecviedQueue);
ReleaseSharedBuffer(ipc->IpcSessionSharedBuffer);
Free(ipc); Free(ipc);
} }

@ -119,6 +119,9 @@
#define IPC_PASSWORD_MSCHAPV2_TAG "xH7DiNlurDhcYV4a:" #define IPC_PASSWORD_MSCHAPV2_TAG "xH7DiNlurDhcYV4a:"
#define IPC_LAYER_2 2
#define IPC_LAYER_3 3
// ARP table entry // ARP table entry
struct IPC_ARP struct IPC_ARP
{ {
@ -138,6 +141,14 @@ struct IPC_DHCP_RELESAE_QUEUE
UCHAR MacAddress[6]; UCHAR MacAddress[6];
}; };
// IPC_SESSION_SHARED_BUFFER_DATA
struct IPC_SESSION_SHARED_BUFFER_DATA
{
char ProtocolDetails[256]; // Protocol Details
bool EnableUdpAccel;
bool UsingUdpAccel;
};
// IPC_PARAM // IPC_PARAM
struct IPC_PARAM struct IPC_PARAM
{ {
@ -156,6 +167,8 @@ struct IPC_PARAM
UINT Mss; UINT Mss;
bool IsL3Mode; bool IsL3Mode;
bool IsOpenVPN; bool IsOpenVPN;
X *ClientCertificate;
UINT Layer;
}; };
// IPC_ASYNC object // IPC_ASYNC object
@ -200,6 +213,9 @@ struct IPC
TUBE_FLUSH_LIST *FlushList; // Tube Flush List TUBE_FLUSH_LIST *FlushList; // Tube Flush List
UCHAR MsChapV2_ServerResponse[20]; // Server response UCHAR MsChapV2_ServerResponse[20]; // Server response
DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table
SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session
IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // A shared data between IPC and Session
UINT Layer;
}; };
// MS-CHAPv2 authentication information // MS-CHAPv2 authentication information
@ -215,7 +231,8 @@ struct IPC_MSCHAP_V2_AUTHINFO
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
char *client_hostname, char *crypt_name, char *client_hostname, char *crypt_name,
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client); bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
UINT layer);
IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code); IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code);
IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address); IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address);
void FreeIPC(IPC *ipc); void FreeIPC(IPC *ipc);

@ -299,7 +299,7 @@ void PPPThread(THREAD *thread, void *param)
IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP); IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP);
eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id); eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id, "L3:PPP");
if (eap) if (eap)
{ {
@ -1009,7 +1009,8 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
// Attempt to connect with IPC // Attempt to connect with IPC
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort, &error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient); p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL,
IPC_LAYER_3);
if (ipc != NULL) if (ipc != NULL)
{ {
@ -1142,7 +1143,8 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort, &error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL); p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL, NULL,
IPC_LAYER_3);
if (ipc != NULL) if (ipc != NULL)
{ {
@ -2616,35 +2618,6 @@ THREAD *NewPPPSession(CEDAR *cedar, IP *client_ip, UINT client_port, IP *server_
return t; return t;
} }
// Generate the NT hash of the password
void GenerateNtPasswordHash(UCHAR *dst, char *password)
{
UCHAR *tmp;
UINT tmp_size;
UINT i, len;
// Validate arguments
if (dst == NULL || password == NULL)
{
return;
}
// Generate a Unicode password
len = StrLen(password);
tmp_size = len * 2;
tmp = ZeroMalloc(tmp_size);
for (i = 0;i < len;i++)
{
tmp[i * 2] = password[i];
}
// Hashing
HashMd4(dst, tmp, tmp_size);
Free(tmp);
}
// Generate the MS-CHAPv2 server-side challenge // Generate the MS-CHAPv2 server-side challenge
void MsChapV2Server_GenerateChallenge(UCHAR *dst) void MsChapV2Server_GenerateChallenge(UCHAR *dst)
{ {

@ -317,7 +317,6 @@ void PPPSendEchoRequest(PPP_SESSION *p);
bool PPPParseUsername(CEDAR *cedar, char *src, ETHERIP_ID *dst); bool PPPParseUsername(CEDAR *cedar, char *src, ETHERIP_ID *dst);
bool IsHubExistsWithLock(CEDAR *cedar, char *hubname); bool IsHubExistsWithLock(CEDAR *cedar, char *hubname);
void GenerateNtPasswordHash(UCHAR *dst, char *password);
void GenerateNtPasswordHashHash(UCHAR *dst_hash, UCHAR *src_hash); void GenerateNtPasswordHashHash(UCHAR *dst_hash, UCHAR *src_hash);
void MsChapV2Server_GenerateChallenge(UCHAR *dst); void MsChapV2Server_GenerateChallenge(UCHAR *dst);
void MsChapV2Client_GenerateChallenge(UCHAR *dst); void MsChapV2Client_GenerateChallenge(UCHAR *dst);

@ -234,7 +234,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
} }
se->Channels[recv_packet->KeyId] = c; se->Channels[recv_packet->KeyId] = c;
Debug("OpenVPN New Channel :%u\n", recv_packet->KeyId); Debug("OpenVPN New Channel :%u\n", recv_packet->KeyId);
OvsLog(s, se, c, "LO_NEW_CHANNEL"); //OvsLog(s, se, c, "LO_NEW_CHANNEL");
} }
/* else if (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1) /* else if (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1)
{ {
@ -294,12 +294,39 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
data = recv_packet->Data; data = recv_packet->Data;
size = recv_packet->DataSize; 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 *hmac;
UCHAR *iv; UCHAR *iv;
UCHAR hmac_test[128]; UCHAR hmac_test[128];
if (size < (c->MdRecv->Size + c->CipherDecrypt->IvSize + sizeof(UINT))) goto decode_error;
// HMAC // HMAC
hmac = data; hmac = data;
data += c->MdRecv->Size; data += c->MdRecv->Size;
@ -307,32 +334,31 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
// Confirmation of HMAC // Confirmation of HMAC
MdProcess(c->MdRecv, hmac_test, data, size); 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;
{
// Update of last communication time
se->LastCommTick = s->Now;
// IV // IV
iv = data; iv = data;
data += c->CipherDecrypt->IvSize; data += c->CipherDecrypt->IvSize;
size -= c->CipherDecrypt->IvSize; size -= c->CipherDecrypt->IvSize;
// Payload
if (size >= 1 && (c->CipherDecrypt->BlockSize == 0 || (size % c->CipherDecrypt->BlockSize) == 0))
{
UINT data_packet_id;
// Decryption // 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); size = CipherProcess(c->CipherDecrypt, iv, s->TmpBuf, data, size);
if(size == 0) goto decode_error;
data = s->TmpBuf; data = s->TmpBuf;
// Seek buffer after the packet ID
if (size >= sizeof(UINT))
{
data_packet_id = READ_UINT(data);
data += sizeof(UINT); data += sizeof(UINT);
size -= 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) && if (size >= sizeof(ping_signature) &&
Cmp(data, ping_signature, sizeof(ping_signature)) == 0) Cmp(data, ping_signature, sizeof(ping_signature)) == 0)
@ -342,7 +368,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
} }
else else
{ {
// Receive a packet!! // Receive a valid data packet!!
if (se->Ipc != NULL) if (se->Ipc != NULL)
{ {
switch (se->Mode) switch (se->Mode)
@ -360,14 +386,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
} }
} }
} }
else decode_error:
{
// Debug("HMAC Failed (c=%u)\n", c->KeyId);
}
}
}
}
}
OvsFreePacket(recv_packet); OvsFreePacket(recv_packet);
} }
@ -433,7 +452,8 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN
// Create an SSL pipe // Create an SSL pipe
Lock(s->Cedar->lock); Lock(s->Cedar->lock);
{ {
c->SslPipe = NewSslPipe(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh); bool cert_verify = true;
c->SslPipe = NewSslPipeEx(true, s->Cedar->ServerX, s->Cedar->ServerK, s->Dh, cert_verify, &c->ClientCert);
} }
Unlock(s->Cedar->lock); Unlock(s->Cedar->lock);
@ -481,7 +501,7 @@ void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN
case OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2: case OPENVPN_P_CONTROL_HARD_RESET_CLIENT_V2:
// New connection (hard reset) // New connection (hard reset)
OvsSendControlPacket(c, OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2, NULL, 0); OvsSendControlPacketEx(c, OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2, NULL, 0, true);
c->Status = OPENVPN_CHANNEL_STATUS_TLS_WAIT_CLIENT_KEY; c->Status = OPENVPN_CHANNEL_STATUS_TLS_WAIT_CLIENT_KEY;
break; break;
@ -703,8 +723,19 @@ void OvsBeginIPCAsyncConnectionIfEmpty(OPENVPN_SERVER *s, OPENVPN_SESSION *se, O
p.BridgeMode = true; p.BridgeMode = true;
} }
if (IsEmptyStr(c->ClientKey.Username) || IsEmptyStr(c->ClientKey.Password))
{
// OpenVPN X.509 certificate authentication is used only when no username / password is specified
if (c->ClientCert.X != NULL)
{
p.ClientCertificate = c->ClientCert.X;
}
}
p.IsOpenVPN = true; p.IsOpenVPN = true;
p.Layer = (se->Mode == OPENVPN_MODE_L2) ? IPC_LAYER_2 : IPC_LAYER_3;
// Calculate the MSS // Calculate the MSS
p.Mss = OvsCalcTcpMss(s, se, c); p.Mss = OvsCalcTcpMss(s, se, c);
Debug("MSS=%u\n", p.Mss); Debug("MSS=%u\n", p.Mss);
@ -758,6 +789,7 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
LIST *o; LIST *o;
BUF *b; BUF *b;
char opt_str[MAX_SIZE]; char opt_str[MAX_SIZE];
char *cipher_name, *md_name;
// Validate arguments // Validate arguments
if (s == NULL || se == NULL || c == NULL || data == NULL) if (s == NULL || se == NULL || c == NULL || data == NULL)
{ {
@ -771,6 +803,26 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
OvsLog(s, se, c, "LO_OPTION_STR_RECV", data->OptionString); OvsLog(s, se, c, "LO_OPTION_STR_RECV", data->OptionString);
if (c->ClientCert.X != NULL)
{
if (c->ClientCert.X->subject_name != NULL)
{
OvsLog(s, se, c, "LO_CLIENT_CERT", c->ClientCert.X->subject_name->CommonName);
}
else
{
OvsLog(s, se, c, "LO_CLIENT_CERT", "(unknown CN)");
}
}
else if (!c->ClientCert.PreverifyErr)
{
OvsLog(s, se, c, "LO_CLIENT_NO_CERT");
}
else
{
OvsLog(s, se, c, "LO_CLIENT_UNVERIFIED_CERT", c->ClientCert.PreverifyErrMessage);
}
Zero(opt_str, sizeof(opt_str)); Zero(opt_str, sizeof(opt_str));
StrCpy(opt_str, sizeof(opt_str), data->OptionString); StrCpy(opt_str, sizeof(opt_str), data->OptionString);
if (s->Cedar != NULL && (IsEmptyStr(opt_str) || StartWith(opt_str, "V0 UNDEF") || InStr(opt_str, ",") == false)) if (s->Cedar != NULL && (IsEmptyStr(opt_str) || StartWith(opt_str, "V0 UNDEF") || InStr(opt_str, ",") == false))
@ -839,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 // Random number generation
Rand(c->ServerKey.Random1, sizeof(c->ServerKey.Random1)); Rand(c->ServerKey.Random1, sizeof(c->ServerKey.Random1));
Rand(c->ServerKey.Random2, sizeof(c->ServerKey.Random2)); Rand(c->ServerKey.Random2, sizeof(c->ServerKey.Random2));
@ -872,13 +916,45 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
c->ExpansionKey, sizeof(c->ExpansionKey)); c->ExpansionKey, sizeof(c->ExpansionKey));
FreeBuf(b); 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->CipherDecrypt, c->ExpansionKey + 0, false);
SetCipherKey(c->CipherEncrypt, c->ExpansionKey + 128, true); SetCipherKey(c->CipherEncrypt, c->ExpansionKey + 128, true);
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->MdRecv, c->ExpansionKey + 64, c->MdRecv->Size);
SetMdKey(c->MdSend, c->ExpansionKey + 192, c->MdSend->Size); SetMdKey(c->MdSend, c->ExpansionKey + 192, c->MdSend->Size);
}
OvsFreeOptions(o); // 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 // Generate the response option string
Format(c->ServerKey.OptionString, sizeof(c->ServerKey.OptionString), Format(c->ServerKey.OptionString, sizeof(c->ServerKey.OptionString),
@ -888,9 +964,11 @@ void OvsSetupSessionParameters(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_C
se->LinkMtu, se->LinkMtu,
se->TunMtu, se->TunMtu,
c->Proto, 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); Debug("Building OptionStr: %s\n", c->ServerKey.OptionString);
OvsFreeOptions(o);
OvsLog(s, se, c, "LO_OPTION_STR_SEND", c->ServerKey.OptionString); OvsLog(s, se, c, "LO_OPTION_STR_SEND", c->ServerKey.OptionString);
} }
@ -899,7 +977,7 @@ CIPHER *OvsGetCipher(char *name)
{ {
CIPHER *c = NULL; CIPHER *c = NULL;
if (IsEmptyStr(name) == false && IsStrInStrTokenList(OPENVPN_CIPHER_LIST, name, NULL, false)) if (IsEmptyStr(name) == false)
{ {
c = NewCipher(name); c = NewCipher(name);
} }
@ -917,7 +995,7 @@ MD *OvsGetMd(char *name)
{ {
MD *m = NULL; MD *m = NULL;
if (IsEmptyStr(name) == false && IsStrInStrTokenList(OPENVPN_MD_LIST, name, NULL, false)) if (IsEmptyStr(name) == false)
{ {
m = NewMd(name); m = NewMd(name);
} }
@ -1235,6 +1313,10 @@ void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *
// Send the control packet // Send the control packet
void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size) void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size)
{
OvsSendControlPacketEx(c, opcode, data, data_size, false);
}
void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size, bool no_resend)
{ {
OPENVPN_CONTROL_PACKET *p; OPENVPN_CONTROL_PACKET *p;
// Validate arguments // Validate arguments
@ -1245,6 +1327,8 @@ void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT da
p = ZeroMalloc(sizeof(OPENVPN_CONTROL_PACKET)); p = ZeroMalloc(sizeof(OPENVPN_CONTROL_PACKET));
p->NoResend = no_resend;
p->OpCode = opcode; p->OpCode = opcode;
p->PacketId = c->NextSendPacketId++; p->PacketId = c->NextSendPacketId++;
@ -1350,6 +1434,11 @@ void OvsFreeChannel(OPENVPN_CHANNEL *c)
FreeMd(c->MdRecv); FreeMd(c->MdRecv);
FreeMd(c->MdSend); FreeMd(c->MdSend);
if (c->ClientCert.X != NULL)
{
FreeX(c->ClientCert.X);
}
Free(c); Free(c);
} }
@ -1376,7 +1465,8 @@ OPENVPN_CHANNEL *OvsNewChannel(OPENVPN_SESSION *se, UCHAR key_id)
c->KeyId = 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; //c->NextRekey = se->Server->Now + (UINT64)5000;
@ -1424,9 +1514,7 @@ UINT64 OvsNewServerSessionId(OPENVPN_SERVER *s)
// Build and submit the OpenVPN data packet // Build and submit the OpenVPN data packet
void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, void *data, UINT data_size) void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, void *data, UINT data_size)
{ {
UCHAR uc; const UCHAR op = ((OPENVPN_P_DATA_V1 << 3) & 0xF8) | (key_id & 0x07);
UCHAR *encrypted_data;
UINT encrypted_size;
UCHAR *dest_data; UCHAR *dest_data;
UINT dest_size; UINT dest_size;
UINT r; UINT r;
@ -1437,40 +1525,68 @@ void OvsSendDataPacket(OPENVPN_CHANNEL *c, UCHAR key_id, UINT data_packet_id, vo
return; return;
} }
uc = ((OPENVPN_P_DATA_V1 << 3) & 0xF8) | (key_id & 0x07);
// Generate the data to be encrypted // 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; // Update variable part (packet ID) of IV
encrypted_data = ZeroMalloc(encrypted_size); 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 // Prepare a buffer to store the results
dest_data = Malloc(sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize + encrypted_size + 256); dest_data = Malloc(sizeof(op) + sizeof(data_packet_id) + sizeof(tag) + data_size + 256);
// Set data size to the maximum known
dest_size = sizeof(op) + sizeof(data_packet_id) + sizeof(tag);
// Write opcode
dest_data[0] = op;
// Write packet ID
WRITE_UINT(dest_data + sizeof(op), data_packet_id);
// 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;
// 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);
// 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 // Encrypt
r = CipherProcess(c->CipherEncrypt, c->NextIv, dest_data + sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize, r = CipherProcess(c->CipherEncrypt, c->IvSend, dest_data + sizeof(op) + c->MdSend->Size + c->CipherEncrypt->IvSize,
encrypted_data, encrypted_size); encrypted_data, encrypted_size);
dest_size = sizeof(UCHAR) + c->MdSend->Size + c->CipherEncrypt->IvSize + r; Free(encrypted_data);
dest_size = sizeof(op) + c->MdSend->Size + c->CipherEncrypt->IvSize + r;
// Copy the IV // Copy the IV
Copy(dest_data + sizeof(UCHAR) + c->MdSend->Size, c->NextIv, c->CipherEncrypt->IvSize); Copy(dest_data + sizeof(op) + c->MdSend->Size, c->IvSend, c->CipherEncrypt->IvSize);
// Calculate the HMAC // Calculate the HMAC
MdProcess(c->MdSend, dest_data + sizeof(UCHAR), dest_data + sizeof(UCHAR) + c->MdSend->Size, MdProcess(c->MdSend, dest_data + sizeof(op), dest_data + sizeof(op) + c->MdSend->Size,
dest_size - sizeof(UCHAR) - c->MdSend->Size); dest_size - sizeof(op) - c->MdSend->Size);
// Update the NextIV // Update the IV for next
Copy(c->NextIv, dest_data + dest_size - c->CipherEncrypt->IvSize, c->CipherEncrypt->IvSize); Copy(c->IvSend, dest_data + dest_size - c->CipherEncrypt->IvSize, c->CipherEncrypt->IvSize);
}
// Op-code
dest_data[0] = uc;
OvsSendPacketRawNow(c->Server, c->Session, dest_data, dest_size); OvsSendPacketRawNow(c->Server, c->Session, dest_data, dest_size);
Free(encrypted_data);
} }
// Build an OpenVPN control packet // Build an OpenVPN control packet
@ -1767,7 +1883,7 @@ OPENVPN_SESSION *OvsNewSession(OPENVPN_SERVER *s, IP *server_ip, UINT server_por
Debug("OpenVPN New Session: %s:%u -> %s:%u Proto=%u\n", server_ip_str, server_port, Debug("OpenVPN New Session: %s:%u -> %s:%u Proto=%u\n", server_ip_str, server_port,
client_ip_str, client_port, protocol); client_ip_str, client_port, protocol);
OvsLog(s, se, NULL, "LO_NEW_SESSION", (protocol == OPENVPN_PROTOCOL_UDP ? "UDP" : "TCP")); //OvsLog(s, se, NULL, "LO_NEW_SESSION", (protocol == OPENVPN_PROTOCOL_UDP ? "UDP" : "TCP"));
return se; return se;
} }
@ -2220,9 +2336,13 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
OPENVPN_CONTROL_PACKET *cp = LIST_DATA(c->SendControlPacketList, k); OPENVPN_CONTROL_PACKET *cp = LIST_DATA(c->SendControlPacketList, k);
if (cp->NextSendTime <= s->Now) if (cp->NextSendTime <= s->Now)
{
if (cp->NoResend == false || cp->NumSent == 0) // To address the UDP reflection amplification attack: https://github.com/SoftEtherVPN/SoftEtherVPN/issues/1001
{ {
OPENVPN_PACKET *p; OPENVPN_PACKET *p;
cp->NumSent++;
num = OvsGetAckReplyList(c, acks); num = OvsGetAckReplyList(c, acks);
p = OvsNewControlPacket(cp->OpCode, j, se->ServerSessionId, num, acks, p = OvsNewControlPacket(cp->OpCode, j, se->ServerSessionId, num, acks,
@ -2237,6 +2357,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
AddInterrupt(s->Interrupt, cp->NextSendTime); AddInterrupt(s->Interrupt, cp->NextSendTime);
} }
} }
}
// If the response with an ACK-only packet is required, respond such that // If the response with an ACK-only packet is required, respond such that
num = OvsGetAckReplyList(c, acks); num = OvsGetAckReplyList(c, acks);
@ -2386,7 +2507,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
OPENVPN_SESSION *se = LIST_DATA(delete_session_list, i); OPENVPN_SESSION *se = LIST_DATA(delete_session_list, i);
Debug("Deleting Session %p\n", se); Debug("Deleting Session %p\n", se);
OvsLog(s, se, NULL, "LO_DELETE_SESSION"); //OvsLog(s, se, NULL, "LO_DELETE_SESSION");
OvsFreeSession(se); OvsFreeSession(se);

@ -118,6 +118,7 @@
#define OPENVPN_MAX_SSL_RECV_BUF_SIZE (256 * 1024) // SSL receive buffer maximum length #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_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 #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_L2 "OPENVPN_L2"
#define OPENVPN_IPC_POSTFIX_L3 "OPENVPN_L3" #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 // MTU
#define OPENVPN_MTU_LINK 1514 // Ethernet MTU #define OPENVPN_MTU_LINK 1514 // Ethernet MTU
#define OPENVPN_MTU_TUN 1500 // Tun MTU #define OPENVPN_MTU_TUN 1500 // Tun MTU
@ -163,6 +158,7 @@
#define OPENVPN_P_DATA_V1 6 // Data packet #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_CLIENT_V2 7 // Connection request from client
#define OPENVPN_P_CONTROL_HARD_RESET_SERVER_V2 8 // Connection response from server #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 // State of OpenVPN channel
#define OPENVPN_CHANNEL_STATUS_INIT 0 // Initialization phase #define OPENVPN_CHANNEL_STATUS_INIT 0 // Initialization phase
@ -204,6 +200,8 @@ struct OPENVPN_CONTROL_PACKET
UINT DataSize; // Data size UINT DataSize; // Data size
UCHAR *Data; // Data body UCHAR *Data; // Data body
UINT64 NextSendTime; // Scheduled next transmission time UINT64 NextSendTime; // Scheduled next transmission time
bool NoResend; // Disable re-sending
UINT NumSent; // How many times we have sent this packet
}; };
// OpenVPN packet // OpenVPN packet
@ -238,9 +236,10 @@ struct OPENVPN_CHANNEL
CIPHER *CipherDecrypt; // Decryption algorithm CIPHER *CipherDecrypt; // Decryption algorithm
MD *MdSend; // Transmission MD algorithm MD *MdSend; // Transmission MD algorithm
MD *MdRecv; // Reception MD algorithm MD *MdRecv; // Reception MD algorithm
UCHAR IvSend[64]; // Transmission IV
UCHAR IvRecv[64]; // Reception IV
UCHAR MasterSecret[48]; // Master Secret UCHAR MasterSecret[48]; // Master Secret
UCHAR ExpansionKey[256]; // Expansion Key UCHAR ExpansionKey[256]; // Expansion Key
UCHAR NextIv[64]; // Next IV
UINT LastDataPacketId; // Previous Data Packet ID UINT LastDataPacketId; // Previous Data Packet ID
UINT64 EstablishedTick; // Established time UINT64 EstablishedTick; // Established time
UCHAR KeyId; // KEY ID UCHAR KeyId; // KEY ID
@ -248,6 +247,7 @@ struct OPENVPN_CHANNEL
bool IsInitiatorServer; // Whether the channel was started from the server side bool IsInitiatorServer; // Whether the channel was started from the server side
bool RekeyInitiated; // Whether re-keying has already started bool RekeyInitiated; // Whether re-keying has already started
UINT64 NextRekey; UINT64 NextRekey;
struct SslClientCertInfo ClientCert; // Client certificate and verification data
}; };
// OpenVPN session // OpenVPN session
@ -342,6 +342,7 @@ void OvsSendPacketRawNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, void *data, UIN
void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_PACKET *p); void OvsProcessRecvControlPacket(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_CHANNEL *c, OPENVPN_PACKET *p);
void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size); void OvsSendControlPacket(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size);
void OvsSendControlPacketEx(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size, bool no_resend);
void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size); void OvsSendControlPacketWithAutoSplit(OPENVPN_CHANNEL *c, UCHAR opcode, UCHAR *data, UINT data_size);
void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p); void OvsFreeControlPacket(OPENVPN_CONTROL_PACKET *p);
void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks); void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UINT *acks);

@ -247,6 +247,9 @@ void TCPAcceptedThread(THREAD *t, void *param)
// Create a connection // Create a connection
c = NewServerConnection(r->Cedar, s, t); c = NewServerConnection(r->Cedar, s, t);
AddRef(r->ref);
c->Listener = r;
// Register to Cedar as a transient connection // Register to Cedar as a transient connection
AddConnection(c->Cedar, c); AddConnection(c->Cedar, c);
@ -264,8 +267,15 @@ void TCPAcceptedThread(THREAD *t, void *param)
ConnectionAccept(c); ConnectionAccept(c);
flag1 = c->flag1; flag1 = c->flag1;
if (c->JsonRpcAuthed)
{
RemoveDosEntry(r, s);
}
// Release // Release
SLog(r->Cedar, "LS_CONNECTION_END_1", c->Name); SLog(r->Cedar, "LS_CONNECTION_END_1", c->Name);
ReleaseListener(c->Listener);
c->Listener = NULL;
ReleaseConnection(c); ReleaseConnection(c);
// Release // Release
@ -302,6 +312,46 @@ void TCPAccepted(LISTENER *r, SOCK *s)
num_clients_from_this_ip = GetNumIpClient(&s->RemoteIP); num_clients_from_this_ip = GetNumIpClient(&s->RemoteIP);
#ifdef USE_DOS_ATTACK_DETECTION
if (disable_dos == false && r->DisableDos == false && r->Protocol != LISTENER_INPROC)
{
UINT max_uec, now_uec;
// DOS attack check
if (CheckDosAttack(r, s) == false)
{
Debug("DOS Attack 1 !!\n");
IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
SLog(r->Cedar, "LS_LISTENER_DOS", r->Port, tmp, s->RemotePort);
return;
}
if (StrCmpi(s->UnderlayProtocol, SOCK_UNDERLAY_NATIVE_V6) == 0 ||
StrCmpi(s->UnderlayProtocol, SOCK_UNDERLAY_NATIVE_V4) == 0)
{
if (IsInNoSsl(r->Cedar, &s->RemoteIP))
{
Debug("DOS Attack 2 !!\n");
IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
SLog(r->Cedar, "LS_LISTENER_DOS", r->Port, tmp, s->RemotePort);
return;
}
}
if (num_clients_from_this_ip > GetMaxConnectionsPerIp())
{
Debug("DOS Attack 3 !!\n");
IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
SLog(r->Cedar, "LS_LISTENER_DOS", r->Port, tmp, s->RemotePort);
return;
}
max_uec = GetMaxUnestablishedConnections();
now_uec = GetUnestablishedConnections(cedar);
if (now_uec > max_uec)
{
Debug("DOS Attack 4 !!\n");
SLog(r->Cedar, "LS_LISTENER_MAXUEC", max_uec, now_uec);
return;
}
}
#endif // USE_DOS_ATTACK_DETECTION
IPToStr(tmp, sizeof(tmp), &s->RemoteIP); IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
@ -320,6 +370,169 @@ void TCPAccepted(LISTENER *r, SOCK *s)
ReleaseThread(t); ReleaseThread(t);
} }
// Remove a DOS entry
bool RemoveDosEntry(LISTENER *r, SOCK *s)
{
DOS *d;
bool ok = false;
// Validate arguments
if (r == NULL || s == NULL)
{
return false;
}
LockList(r->DosList);
{
// Delete old entries from the DOS attack list
RefreshDosList(r);
// Search the table
d = SearchDosList(r, &s->RemoteIP);
if (d != NULL)
{
Delete(r->DosList, d);
Free(d);
ok = true;
}
}
UnlockList(r->DosList);
return ok;
}
// Check whether this is a DOS attack
bool CheckDosAttack(LISTENER *r, SOCK *s)
{
DOS *d;
bool ok = true;
// Validate arguments
if (r == NULL || s == NULL)
{
return false;
}
LockList(r->DosList);
{
// Delete old entries from the DOS attack list
RefreshDosList(r);
// Search the table
d = SearchDosList(r, &s->RemoteIP);
if (d != NULL)
{
// There is a entry already
// This should mean being under a DOS attack
d->LastConnectedTick = Tick64();
d->CurrentExpireSpan = MIN(d->CurrentExpireSpan * (UINT64)2, DOS_TABLE_EXPIRES_MAX);
d->AccessCount++;
if (d->AccessCount > DOS_TABLE_MAX_LIMIT_PER_IP)
{
ok = false;
}
}
else
{
// Create a new entry
d = ZeroMalloc(sizeof(DOS));
d->CurrentExpireSpan = (UINT64)DOS_TABLE_EXPIRES_FIRST;
d->FirstConnectedTick = d->LastConnectedTick = Tick64();
d->AccessCount = 1;
d->DeleteEntryTick = d->FirstConnectedTick + (UINT64)DOS_TABLE_EXPIRES_TOTAL;
Copy(&d->IpAddress, &s->RemoteIP, sizeof(IP));
Add(r->DosList, d);
}
}
UnlockList(r->DosList);
return ok;
}
// Delete old entries from the DOS attack list
void RefreshDosList(LISTENER *r)
{
// Validate arguments
if (r == NULL)
{
return;
}
if (r->DosListLastRefreshTime == 0 ||
(r->DosListLastRefreshTime + (UINT64)DOS_TABLE_REFRESH_INTERVAL) <= Tick64())
{
UINT i;
LIST *o;
r->DosListLastRefreshTime = Tick64();
o = NewListFast(NULL);
for (i = 0;i < LIST_NUM(r->DosList);i++)
{
DOS *d = LIST_DATA(r->DosList, i);
if ((d->LastConnectedTick + d->CurrentExpireSpan) <= Tick64() ||
(d->DeleteEntryTick <= Tick64()))
{
Add(o, d);
}
}
for (i = 0;i < LIST_NUM(o);i++)
{
DOS *d = LIST_DATA(o, i);
Delete(r->DosList, d);
Free(d);
}
ReleaseList(o);
}
}
// Search the DOS attack list by the IP address
DOS *SearchDosList(LISTENER *r, IP *ip)
{
DOS *d, t;
// Validate arguments
if (r == NULL || ip == NULL)
{
return NULL;
}
Copy(&t.IpAddress, ip, sizeof(IP));
d = Search(r->DosList, &t);
if (d != NULL)
{
if ((d->LastConnectedTick + d->CurrentExpireSpan) <= Tick64() ||
(d->DeleteEntryTick <= Tick64()))
{
// Delete old entries
Delete(r->DosList, d);
Free(d);
return NULL;
}
}
return d;
}
// Comparison of DOS attack list entries
int CompareDos(void *p1, void *p2)
{
DOS *d1, *d2;
if (p1 == NULL || p2 == NULL)
{
return 0;
}
d1 = *(DOS **)p1;
d2 = *(DOS **)p2;
if (d1 == NULL || d2 == NULL)
{
return 0;
}
return CmpIpAddr(&d1->IpAddress, &d2->IpAddress);
}
// UDP listener main loop // UDP listener main loop
void ListenerUDPMainLoop(LISTENER *r) void ListenerUDPMainLoop(LISTENER *r)
@ -869,6 +1082,7 @@ LISTENER *NewListenerEx5(CEDAR *cedar, UINT proto, UINT port, THREAD_PROC *proc,
r->Port = port; r->Port = port;
r->Event = NewEvent(); r->Event = NewEvent();
r->DosList = NewList(CompareDos);
r->LocalOnly = local_only; r->LocalOnly = local_only;
r->ShadowIPv6 = shadow_ipv6; r->ShadowIPv6 = shadow_ipv6;

@ -109,6 +109,16 @@
// Function to call when receiving a new connection // Function to call when receiving a new connection
typedef void (NEW_CONNECTION_PROC)(CONNECTION *c); typedef void (NEW_CONNECTION_PROC)(CONNECTION *c);
// DOS attack list
struct DOS
{
IP IpAddress; // IP address
UINT64 FirstConnectedTick; // Time which a client connects at the first time
UINT64 LastConnectedTick; // Time which a client connected at the last time
UINT64 CurrentExpireSpan; // Current time-out period of this record
UINT64 DeleteEntryTick; // Time planned to delete this entry
UINT AccessCount; // The number of accesses
};
// Listener structure // Listener structure
@ -125,6 +135,8 @@ struct LISTENER
volatile bool Halt; // Halting flag volatile bool Halt; // Halting flag
UINT Status; // State UINT Status; // State
LIST *DosList; // DOS attack list
UINT64 DosListLastRefreshTime; // Time that the DOS list is refreshed at the last
THREAD_PROC *ThreadProc; // Thread procedure THREAD_PROC *ThreadProc; // Thread procedure
void *ThreadParam; // Thread parameters void *ThreadParam; // Thread parameters
@ -199,6 +211,11 @@ void FreeDynamicListener(DYNAMIC_LISTENER *d);
bool ListenerRUDPRpcRecvProc(RUDP_STACK *r, UDPPACKET *p); bool ListenerRUDPRpcRecvProc(RUDP_STACK *r, UDPPACKET *p);
void ListenerSetProcRecvRpcEnable(bool b); void ListenerSetProcRecvRpcEnable(bool b);
int CompareDos(void *p1, void *p2);
DOS *SearchDosList(LISTENER *r, IP *ip);
void RefreshDosList(LISTENER *r);
bool CheckDosAttack(LISTENER *r, SOCK *s);
bool RemoveDosEntry(LISTENER *r, SOCK *s);
#endif // LISTENER_H #endif // LISTENER_H

@ -1147,11 +1147,23 @@ bool PacketLog(HUB *hub, SESSION *src_session, SESSION *dest_session, PKT *packe
if (src_session != NULL && src_session->NormalClient) if (src_session != NULL && src_session->NormalClient)
{ {
StrCpy(pl->SrcPhysicalIP, sizeof(pl->SrcPhysicalIP), src_session->ClientIP); StrCpy(pl->SrcPhysicalIP, sizeof(pl->SrcPhysicalIP), src_session->ClientIP);
if (src_session->ClientPort != 0)
{
char tmp[32] = {0};
Format(tmp, sizeof(tmp), "(port=%u)", src_session->ClientPort);
StrCat(pl->SrcPhysicalIP, sizeof(pl->SrcPhysicalIP), tmp);
}
} }
if (dest_session != NULL && dest_session->NormalClient) if (dest_session != NULL && dest_session->NormalClient)
{ {
StrCpy(pl->DestPhysicalIP, sizeof(pl->DestPhysicalIP), dest_session->ClientIP); StrCpy(pl->DestPhysicalIP, sizeof(pl->DestPhysicalIP), dest_session->ClientIP);
if (dest_session->ClientPort != 0)
{
char tmp[32] = {0};
Format(tmp, sizeof(tmp), "(port=%u)", dest_session->ClientPort);
StrCat(pl->DestPhysicalIP, sizeof(pl->DestPhysicalIP), tmp);
}
} }
pl->WritePhysicalIP = true; pl->WritePhysicalIP = true;
@ -1430,6 +1442,7 @@ char *BuildHttpLogStr(HTTPLOG *h)
AddLogBufToStr(b, "HttpProtocol", h->Protocol); AddLogBufToStr(b, "HttpProtocol", h->Protocol);
AddLogBufToStr(b, "HttpReferer", h->Referer); AddLogBufToStr(b, "HttpReferer", h->Referer);
AddLogBufToStr(b, "HttpUserAgent", h->UserAgent); AddLogBufToStr(b, "HttpUserAgent", h->UserAgent);
AddLogBufToStr(b, "HttpAcceptLanguage", h->AcceptLanguage);
WriteBuf(b, &nullchar, 1); WriteBuf(b, &nullchar, 1);
@ -1478,12 +1491,19 @@ void AddLogBufToStr(BUF *b, char *name, char *value)
void MakeSafeLogStr(char *str) void MakeSafeLogStr(char *str)
{ {
UINT i, len; UINT i, len;
bool is_http = false;
// Validate arguments // Validate arguments
if (str == NULL) if (str == NULL)
{ {
return; return;
} }
if (str[0] == 'h' && str[1] == 't' && str[2] == 't' && str[3] == 'p' &&
((str[4] == 's' && str[5] == ':') || (str[4] == ':')))
{
is_http = true;
}
EnPrintableAsciiStr(str, '?'); EnPrintableAsciiStr(str, '?');
len = StrLen(str); len = StrLen(str);
@ -1494,10 +1514,13 @@ void MakeSafeLogStr(char *str)
str[i] = '.'; str[i] = '.';
} }
else if (str[i] == ' ') else if (str[i] == ' ')
{
if (is_http == false)
{ {
str[i] = '_'; str[i] = '_';
} }
} }
}
} }
// Procedure for converting a packet log entry to a string // Procedure for converting a packet log entry to a string
@ -2242,8 +2265,6 @@ void ReplaceForCsv(char *str)
return; return;
} }
// If there are blanks, trim it
Trim(str);
len = StrLen(str); len = StrLen(str);
for (i = 0;i < len;i++) for (i = 0;i < len;i++)

@ -895,18 +895,21 @@ void OutRpcEnumDhcp(PACK *p, RPC_ENUM_DHCP *t)
PackAddInt(p, "NumItem", t->NumItem); PackAddInt(p, "NumItem", t->NumItem);
PackAddStr(p, "HubName", t->HubName); PackAddStr(p, "HubName", t->HubName);
PackSetCurrentJsonGroupName(p, "DhcpTable");
for (i = 0;i < t->NumItem;i++) for (i = 0;i < t->NumItem;i++)
{ {
RPC_ENUM_DHCP_ITEM *e = &t->Items[i]; RPC_ENUM_DHCP_ITEM *e = &t->Items[i];
PackAddIntEx(p, "Id", e->Id, i, t->NumItem); PackAddIntEx(p, "Id", e->Id, i, t->NumItem);
PackAddInt64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem); PackAddTime64Ex(p, "LeasedTime", e->LeasedTime, i, t->NumItem);
PackAddInt64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem); PackAddTime64Ex(p, "ExpireTime", e->ExpireTime, i, t->NumItem);
PackAddDataEx(p, "MacAddress", e->MacAddress, 6, i, t->NumItem); PackAddDataEx(p, "MacAddress", e->MacAddress, 6, i, t->NumItem);
PackAddIp32Ex(p, "IpAddress", e->IpAddress, i, t->NumItem); PackAddIp32Ex(p, "IpAddress", e->IpAddress, i, t->NumItem);
PackAddIntEx(p, "Mask", e->Mask, i, t->NumItem); PackAddIntEx(p, "Mask", e->Mask, i, t->NumItem);
PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumItem); PackAddStrEx(p, "Hostname", e->Hostname, i, t->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
} }
void FreeRpcEnumDhcp(RPC_ENUM_DHCP *t) void FreeRpcEnumDhcp(RPC_ENUM_DHCP *t)
{ {
@ -963,6 +966,8 @@ void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t)
PackAddInt(p, "NumItem", t->NumItem); PackAddInt(p, "NumItem", t->NumItem);
PackAddStr(p, "HubName", t->HubName); PackAddStr(p, "HubName", t->HubName);
PackSetCurrentJsonGroupName(p, "NatTable");
for (i = 0;i < t->NumItem;i++) for (i = 0;i < t->NumItem;i++)
{ {
RPC_ENUM_NAT_ITEM *e = &t->Items[i]; RPC_ENUM_NAT_ITEM *e = &t->Items[i];
@ -975,12 +980,13 @@ void OutRpcEnumNat(PACK *p, RPC_ENUM_NAT *t)
PackAddIp32Ex(p, "DestIp", e->DestIp, i, t->NumItem); PackAddIp32Ex(p, "DestIp", e->DestIp, i, t->NumItem);
PackAddStrEx(p, "DestHost", e->DestHost, i, t->NumItem); PackAddStrEx(p, "DestHost", e->DestHost, i, t->NumItem);
PackAddIntEx(p, "DestPort", e->DestPort, i, t->NumItem); PackAddIntEx(p, "DestPort", e->DestPort, i, t->NumItem);
PackAddInt64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem); PackAddTime64Ex(p, "CreatedTime", e->CreatedTime, i, t->NumItem);
PackAddInt64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem); PackAddTime64Ex(p, "LastCommTime", e->LastCommTime, i, t->NumItem);
PackAddInt64Ex(p, "SendSize", e->SendSize, i, t->NumItem); PackAddInt64Ex(p, "SendSize", e->SendSize, i, t->NumItem);
PackAddInt64Ex(p, "RecvSize", e->RecvSize, i, t->NumItem); PackAddInt64Ex(p, "RecvSize", e->RecvSize, i, t->NumItem);
PackAddIntEx(p, "TcpStatus", e->TcpStatus, i, t->NumItem); PackAddIntEx(p, "TcpStatus", e->TcpStatus, i, t->NumItem);
} }
PackSetCurrentJsonGroupName(p, NULL);
} }
void FreeRpcEnumNat(RPC_ENUM_NAT *t) void FreeRpcEnumNat(RPC_ENUM_NAT *t)
{ {

File diff suppressed because it is too large Load Diff

@ -105,6 +105,13 @@
#ifndef PROTOCOL_H #ifndef PROTOCOL_H
#define PROTOCOL_H #define PROTOCOL_H
// MIME types
struct HTTP_MIME_TYPE
{
char *Extension;
char *MimeType;
};
// The parameters that will be passed to the certificate confirmation thread // The parameters that will be passed to the certificate confirmation thread
struct CHECK_CERT_THREAD_PROC struct CHECK_CERT_THREAD_PROC
{ {
@ -195,6 +202,76 @@ struct UPDATE_CLIENT
#define PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGKEY "Software\\" GC_REG_COMPANY_NAME "\\" CEDAR_PRODUCT_STR " VPN\\Client Update Notification" #define PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGKEY "Software\\" GC_REG_COMPANY_NAME "\\" CEDAR_PRODUCT_STR " VPN\\Client Update Notification"
#define PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGVALUE "Suppress" #define PROTO_SUPPRESS_CLIENT_UPDATE_NOTIFICATION_REGVALUE "Suppress"
// WebSocket
struct WS
{
SOCK *Sock;
WSP *Wsp;
REF *Ref;
bool Disconnected;
UINT MaxBufferSize;
UCHAR TmpBuf[65536];
};
// WebSocket Protocol
struct WSP
{
UINT MaxBufferSize;
FIFO *PhysicalSendFifo; // WSP -> Network
FIFO *PhysicalRecvFifo; // WSP <- Network
FIFO *AppSendFifo; // APP -> WSP
FIFO *AppRecvFifo; // APP <- WSP
bool HasError;
};
// WebSocket constants
#define WS_MAX_PAYLOAD_LEN_PER_FRAME (8 * 1024 * 1024)
#define WS_SEND_SINGLE_FRAGMENT_SIZE (32 * 1024)
#define WS_OPCODE_CONTINUE 0x00
#define WS_OPCODE_TEXT 0x01
#define WS_OPCODE_BIN 0x02
#define WS_OPCODE_CLOSE 0x08
#define WS_OPCODE_PING 0x09
#define WS_OPCODE_PONG 0x0A
// MVPN constants
#define MVPN_VERSION_MIN 100
#define MVPN_VERSION_CURRENT 100
#define MVPN_MAX_AUTH_RETRY 10
#define MVPN_CLIENT_NAME "Modern VPN Client"
#define NVPN_POSTFIX "MVPN"
// MVPN protocol constants
#define MVPN_AUTHTYPE_ANONYMOUS "anonymous"
#define MVPN_AUTHTYPE_PASSWORD_PLAIN "password_plain"
#define MVPN_AUTHTYPE_PASSWORD_MSCHAPV2 "password_mschapv2"
#define MVPN_AUTHTYPE_CERT "x509cert"
#define MVPN_HEARTBEAT_INTERVAL_DEFAULT 1234
#define MVPN_HEARTBEAT_INTERVAL_MIN 100
#define MVPN_HEARTBEAT_INTERVAL_MAX 15000
#define MVPN_DISCONNECT_TIMEOUT_DEFAULT 15000
#define MVPN_DISCONNECT_TIMEOUT_MIN 5000
#define MVPN_DISCONNECT_TIMEOUT_MAX 60000
#define MVPN_PACKET_MAGIC_NUMBER 0xCAFEBEEF
#define MVPN_PACKET_TYPE_ETHERNET 0
#define MVPN_PACKET_TYPE_IPV4 1
#define MVPN_PACKET_TYPE_HEARTBEAT 254
#define MVPN_ADDRESS_TYPE_STATIC "static"
#define MVPN_ADDRESS_TYPE_DYNAMIC "dynamic"
#define MVPN_AUTHTYPE_ALL_SUPPORTED MVPN_AUTHTYPE_ANONYMOUS "," MVPN_AUTHTYPE_PASSWORD_PLAIN "," MVPN_AUTHTYPE_PASSWORD_MSCHAPV2 "," MVPN_AUTHTYPE_CERT
// Function prototype // Function prototype
UPDATE_CLIENT *NewUpdateClient(UPDATE_NOTIFY_PROC *cb, UPDATE_ISFOREGROUND_PROC *isforeground_cb, void *param, char *family_name, char *software_name, wchar_t *software_title, UINT my_build, UINT64 my_date, char *my_lang, UPDATE_CLIENT_SETTING *current_setting, char *client_id); UPDATE_CLIENT *NewUpdateClient(UPDATE_NOTIFY_PROC *cb, UPDATE_ISFOREGROUND_PROC *isforeground_cb, void *param, char *family_name, char *software_name, wchar_t *software_title, UINT my_build, UINT64 my_date, char *my_lang, UPDATE_CLIENT_SETTING *current_setting, char *client_id);
void FreeUpdateClient(UPDATE_CLIENT *c); void FreeUpdateClient(UPDATE_CLIENT *c);
@ -233,6 +310,7 @@ PACK *PackLoginWithAnonymous(char *hubname, char *username);
PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password); PACK *PackLoginWithPassword(char *hubname, char *username, void *secure_password);
PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_password); PACK *PackLoginWithPlainPassword(char *hubname, char *username, void *plain_password);
PACK *PackLoginWithCert(char *hubname, char *username, X *x, void *sign, UINT sign_size); PACK *PackLoginWithCert(char *hubname, char *username, X *x, void *sign, UINT sign_size);
PACK *PackLoginWithOpenVPNCertificate(char *hubname, char *username, X *x);
bool GetMethodFromPack(PACK *p, char *method, UINT size); bool GetMethodFromPack(PACK *p, char *method, UINT size);
bool GetHubnameAndUsernameFromPack(PACK *p, char *username, UINT username_size, bool GetHubnameAndUsernameFromPack(PACK *p, char *username, UINT username_size,
char *hubname, UINT hubname_size); char *hubname, UINT hubname_size);
@ -302,6 +380,36 @@ X *FindCertIssuerFromCertList(LIST *o, X *x);
bool TryGetRootCertChain(LIST *o, X *x, bool auto_save, X **found_root_x); bool TryGetRootCertChain(LIST *o, X *x, bool auto_save, X **found_root_x);
bool TryGetParentCertFromCertList(LIST *o, X *x, LIST *found_chain); bool TryGetParentCertFromCertList(LIST *o, X *x, LIST *found_chain);
bool DownloadAndSaveIntermediateCertificatesIfNecessary(X *x); bool DownloadAndSaveIntermediateCertificatesIfNecessary(X *x);
char *GetMimeTypeFromFileName(char *filename);
void MvpnProcGet(CONNECTION *c, SOCK *s, HTTP_HEADER *h, char *url_target);
bool MvpnSendReply(SOCK *s, UINT status_code, char *status_string, UCHAR *data, UINT data_size, char *content_type,
char *add_header_name, char *add_header_value, HTTP_HEADER *request_headers);
void MvpnAccept(CONNECTION *c, SOCK *s);
UINT MvpnDoAccept(CONNECTION *c, WS *w);
WS *NewWs(SOCK *s);
void ReleaseWs(WS *w);
void CleanupWs(WS *w);
UINT WsRecvSync(WS *w, void *data, UINT size);
bool WsRecvSyncAll(WS *w, void *data, UINT size);
bool WsSendSync(WS *w, void *data, UINT size);
UINT WsRecvAsync(WS *w, void *data, UINT size);
UINT WsSendAsync(WS *w, void *data, UINT size);
bool WsTrySendAsync(WS *w);
PACK *WsRecvPack(WS *w);
bool WsSendPack(WS *w, PACK *p);
PACK *WsNewErrorPack(UINT err);
char *WsErrorCodeToString(UINT err);
WSP *NewWsp();
void FreeWsp(WSP *p);
void WspTry(WSP *p);
BLOCK *WspTryRecvNextFrame(WSP *p, UINT *read_buffer_size);
void WspTrySendFrame(WSP *p, UCHAR opcode, void *data, UINT size);
#endif // PROTOCOL_H #endif // PROTOCOL_H

@ -314,11 +314,11 @@ bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size)
fragments = NewListFast(NULL); fragments = NewListFast(NULL);
for (num = 0;;num++) for (num = 0;;num++)
{ {
UCHAR tmp[1024]; UCHAR tmp[200];
EAP_PEAP *send_peap_message; EAP_PEAP *send_peap_message;
UINT sz; UINT sz;
sz = ReadBuf(buf, tmp, 1024); sz = ReadBuf(buf, tmp, sizeof(tmp));
if (sz == 0) if (sz == 0)
{ {
@ -690,6 +690,11 @@ void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e)
Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_NAS_ID, 0, 0, CEDAR_SERVER_STR, StrLen(CEDAR_SERVER_STR))); Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_NAS_ID, 0, 0, CEDAR_SERVER_STR, StrLen(CEDAR_SERVER_STR)));
if (IsEmptyStr(e->In_VpnProtocolState) == false)
{
Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_PROXY_STATE, 0, 0, e->In_VpnProtocolState, StrLen(e->In_VpnProtocolState)));
}
ui = Endian32(2); ui = Endian32(2);
Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, Add(r->AvpList, NewRadiusAvp(RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT,
RADIUS_MS_NETWORK_ACCESS_SERVER_TYPE, &ui, sizeof(UINT))); RADIUS_MS_NETWORK_ACCESS_SERVER_TYPE, &ui, sizeof(UINT)));
@ -1011,11 +1016,27 @@ RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r)
{ {
RADIUS_AVP *eap_msg = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_EAP_MESSAGE); RADIUS_AVP *eap_msg = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_EAP_MESSAGE);
RADIUS_AVP *vlan_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_VLAN_ID); RADIUS_AVP *vlan_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_VLAN_ID);
RADIUS_AVP *framed_interface_id_avp = GetRadiusAvp(rp, RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID);
if (eap_msg != NULL) if (eap_msg != NULL)
{ {
e->LastRecvEapId = ((EAP_MESSAGE *)(eap_msg->Data))->Id; e->LastRecvEapId = ((EAP_MESSAGE *)(eap_msg->Data))->Id;
} }
if (framed_interface_id_avp != NULL)
{
// FRAMED_INTERFACE_ID
char tmp_str[64];
UCHAR mac_address[6];
Zero(tmp_str, sizeof(tmp_str));
Copy(tmp_str, framed_interface_id_avp->Data, MIN(framed_interface_id_avp->DataSize, sizeof(tmp_str) - 1));
if (StrToMac(mac_address, tmp_str))
{
Copy(e->LastRecvVirtualMacAddress, mac_address, 6);
}
}
if (vlan_avp != NULL) if (vlan_avp != NULL)
{ {
// VLAN ID // VLAN ID
@ -1700,7 +1721,7 @@ LABEL_ERROR:
// Attempts Radius authentication (with specifying retry interval and multiple server) // 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, 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 random[MD5_SIZE];
UCHAR id; UCHAR id;
@ -1746,6 +1767,11 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
// Try the EAP authentication for RADIUS first // Try the EAP authentication for RADIUS first
EAP_CLIENT *eap = mschap.MsChapV2_EapClient; EAP_CLIENT *eap = mschap.MsChapV2_EapClient;
if (IsEmptyStr(opt->In_VpnProtocolState) == false)
{
StrCpy(eap->In_VpnProtocolState, sizeof(eap->In_VpnProtocolState), opt->In_VpnProtocolState);
}
if (eap->PeapMode == false) if (eap->PeapMode == false)
{ {
ret = EapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse, ret = EapClientSendMsChapv2AuthClientResponse(eap, mschap.MsChapV2_ClientResponse,
@ -1766,6 +1792,8 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
opt->Out_VLanId = eap->LastRecvVLanId; opt->Out_VLanId = eap->LastRecvVLanId;
} }
Copy(opt->Out_VirtualMacAddress, eap->LastRecvVirtualMacAddress, 6);
return true; return true;
} }
else else
@ -1862,6 +1890,10 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
USHORT sz = 0; USHORT sz = 0;
UINT pos = 0; UINT pos = 0;
BOOL *finish = ZeroMallocEx(sizeof(BOOL) * LIST_NUM(ip_list), true); 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)); Zero(tmp, sizeof(tmp));
@ -1880,31 +1912,31 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
// Service-Type // Service-Type
ui = Endian32(2); ui = Endian32(2);
RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui));
// NAS-Port-Type // NAS-Port-Type
ui = Endian32(5); ui = Endian32(5);
RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_PORT_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Type // Tunnel-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Medium-Type // Tunnel-Medium-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE, 0, 0, &ui, sizeof(ui));
// Called-Station-ID - VPN Hub Name // Called-Station-ID - VPN Hub Name
if (IsEmptyStr(hubname) == false) if (IsEmptyStr(hubname) == false)
{ {
RadiusAddValue(p, 30, 0, 0, hubname, StrLen(hubname)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLED_STATION_ID, 0, 0, hubname, StrLen(hubname));
} }
// Calling-Station-Id // Calling-Station-Id
RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLING_STATION_ID, 0, 0, client_ip_str, StrLen(client_ip_str));
// Tunnel-Client-Endpoint // Tunnel-Client-Endpoint
RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT, 0, 0, client_ip_str, StrLen(client_ip_str));
} }
else else
{ {
@ -1918,72 +1950,96 @@ bool RadiusLogin(CONNECTION *c, char *server, UINT port, UCHAR *secret, UINT sec
// Acct-Session-Id // Acct-Session-Id
us = Endian16(session_id % 254 + 1); us = Endian16(session_id % 254 + 1);
session_id++; session_id++;
RadiusAddValue(p, 44, 0, 0, &us, sizeof(us)); RadiusAddValue(p, RADIUS_ATTRIBUTE_ACCT_SESSION_ID, 0, 0, &us, sizeof(us));
// NAS-IP-Address // NAS-IP-Address
if (c != NULL && c->FirstSock != NULL && c->FirstSock->IPv6 == false) if (c != NULL && c->FirstSock != NULL && c->FirstSock->IPv6 == false)
{ {
ui = IPToUINT(&c->FirstSock->LocalIP); ui = IPToUINT(&c->FirstSock->LocalIP);
RadiusAddValue(p, 4, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_IP, 0, 0, &ui, sizeof(ui));
} }
// Service-Type // Service-Type
ui = Endian32(2); ui = Endian32(2);
RadiusAddValue(p, 6, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_SERVICE_TYPE, 0, 0, &ui, sizeof(ui));
// MS-RAS-Vendor // MS-RAS-Vendor
ui = Endian32(311); ui = Endian32(RADIUS_VENDOR_MICROSOFT);
RadiusAddValue(p, 26, 311, 9, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_VENDOR, &ui, sizeof(ui));
// MS-RAS-Version // MS-RAS-Version
RadiusAddValue(p, 26, 311, 18, ms_ras_version, StrLen(ms_ras_version)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_VERSION, ms_ras_version, StrLen(ms_ras_version));
// NAS-Port-Type // NAS-Port-Type
ui = Endian32(5); ui = Endian32(5);
RadiusAddValue(p, 61, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_NAS_PORT_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Type // Tunnel-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 64, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_TYPE, 0, 0, &ui, sizeof(ui));
// Tunnel-Medium-Type // Tunnel-Medium-Type
ui = Endian32(1); ui = Endian32(1);
RadiusAddValue(p, 65, 0, 0, &ui, sizeof(ui)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE, 0, 0, &ui, sizeof(ui));
// Called-Station-ID - VPN Hub Name // Called-Station-ID - VPN Hub Name
if (IsEmptyStr(hubname) == false) if (IsEmptyStr(hubname) == false)
{ {
RadiusAddValue(p, 30, 0, 0, hubname, StrLen(hubname)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLED_STATION_ID, 0, 0, hubname, StrLen(hubname));
} }
// Calling-Station-Id // Calling-Station-Id
RadiusAddValue(p, 31, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_CALLING_STATION_ID, 0, 0, client_ip_str, StrLen(client_ip_str));
// Tunnel-Client-Endpoint // Tunnel-Client-Endpoint
RadiusAddValue(p, 66, 0, 0, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT, 0, 0, client_ip_str, StrLen(client_ip_str));
// MS-RAS-Client-Version // MS-RAS-Client-Version
RadiusAddValue(p, 26, 311, 35, ms_ras_version, StrLen(ms_ras_version)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_CLIENT_VERSION, ms_ras_version, StrLen(ms_ras_version));
// MS-RAS-Client-Name // MS-RAS-Client-Name
RadiusAddValue(p, 26, 311, 34, client_ip_str, StrLen(client_ip_str)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_RAS_CLIENT_NAME, client_ip_str, StrLen(client_ip_str));
// MS-CHAP-Challenge // MS-CHAP-Challenge
RadiusAddValue(p, 26, 311, 11, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_CHAP_CHALLENGE, mschap.MsChapV2_ServerChallenge, sizeof(mschap.MsChapV2_ServerChallenge));
// MS-CHAP2-Response // MS-CHAP2-Response
Zero(ms_chapv2_response, sizeof(ms_chapv2_response)); Zero(ms_chapv2_response, sizeof(ms_chapv2_response));
Copy(ms_chapv2_response + 2, mschap.MsChapV2_ClientChallenge, 16); Copy(ms_chapv2_response + 2, mschap.MsChapV2_ClientChallenge, 16);
Copy(ms_chapv2_response + 2 + 16 + 8, mschap.MsChapV2_ClientResponse, 24); Copy(ms_chapv2_response + 2 + 16 + 8, mschap.MsChapV2_ClientResponse, 24);
RadiusAddValue(p, 26, 311, 25, ms_chapv2_response, sizeof(ms_chapv2_response)); RadiusAddValue(p, RADIUS_ATTRIBUTE_VENDOR_SPECIFIC, RADIUS_VENDOR_MICROSOFT, RADIUS_MS_CHAP2_RESPONSE, ms_chapv2_response, sizeof(ms_chapv2_response));
// NAS-ID // NAS-ID
WriteBuf(p, nas_id->Buf, nas_id->Size); WriteBuf(p, nas_id->Buf, nas_id->Size);
} }
if (IsEmptyStr(opt->In_VpnProtocolState) == false)
{
// Proxy state as protocol details
RadiusAddValue(p, RADIUS_ATTRIBUTE_PROXY_STATE, 0, 0, opt->In_VpnProtocolState, StrLen(opt->In_VpnProtocolState));
}
if (RadiusRequireMessageAuthenticator == false)
{
SeekBuf(p, 0, 0); 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 // Create a socket
sock = NewUDPEx(0, IsIP6(LIST_DATA(ip_list, pos))); sock = NewUDPEx(0, IsIP6(LIST_DATA(ip_list, pos)));
@ -2070,8 +2126,26 @@ RECV_RETRY:
} }
// Success // Success
if (recv_buf[0] == 2) if (recv_buf[0] == 2)
{
LIST *o;
BUF *buf = NewBufFromMemory(recv_buf, recv_size);
if (RadiusRequireMessageAuthenticator == false)
{ {
ret = true; 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) if (is_mschap && mschap_v2_server_response_20 != NULL)
{ {
@ -2108,12 +2182,26 @@ RECV_RETRY:
} }
} }
if (opt->In_CheckVLanId) o = RadiusParseOptions(buf);
{
BUF *buf = NewBufFromMemory(recv_buf, recv_size);
LIST *o = RadiusParseOptions(buf);
if (o != NULL) if (o != NULL)
{
DHCP_OPTION *framed_interface_id_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID);
if (framed_interface_id_option != NULL)
{
char tmp_str[64];
UCHAR mac_address[6];
Zero(tmp_str, sizeof(tmp_str));
Copy(tmp_str, framed_interface_id_option->Data, MIN(framed_interface_id_option->Size, sizeof(tmp_str) - 1));
if (StrToMac(mac_address, tmp_str))
{
Copy(opt->Out_VirtualMacAddress, mac_address, 6);
}
}
if (opt->In_CheckVLanId)
{ {
DHCP_OPTION *vlan_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_VLAN_ID); DHCP_OPTION *vlan_option = GetDhcpOption(o, RADIUS_ATTRIBUTE_VLAN_ID);
@ -2132,9 +2220,10 @@ RECV_RETRY:
} }
} }
FreeBuf(buf);
FreeDhcpOptions(o); FreeDhcpOptions(o);
} }
FreeBuf(buf);
} }
break; break;
} }
@ -2169,6 +2258,156 @@ RECV_RETRY:
return ret; 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 // Parse RADIUS attributes
LIST *RadiusParseOptions(BUF *b) LIST *RadiusParseOptions(BUF *b)
{ {

@ -133,6 +133,7 @@
#define RADIUS_ATTRIBUTE_EAP_MESSAGE 79 #define RADIUS_ATTRIBUTE_EAP_MESSAGE 79
#define RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR 80 #define RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR 80
#define RADIUS_ATTRIBUTE_VLAN_ID 81 #define RADIUS_ATTRIBUTE_VLAN_ID 81
#define RADIUS_ATTRIBUTE_FRAMED_INTERFACE_ID 96
#define RADIUS_MAX_NAS_ID_LEN 253 #define RADIUS_MAX_NAS_ID_LEN 253
// RADIUS codes // RADIUS codes
@ -327,6 +328,9 @@ struct EAP_CLIENT
UCHAR RecvLastCode; UCHAR RecvLastCode;
UINT LastRecvVLanId; UINT LastRecvVLanId;
UCHAR LastRecvVirtualMacAddress[6];
char In_VpnProtocolState[64];
}; };
void FreeRadiusPacket(RADIUS_PACKET *p); void FreeRadiusPacket(RADIUS_PACKET *p);
@ -365,17 +369,20 @@ struct RADIUS_LOGIN_OPTION
UINT Out_VLanId; UINT Out_VLanId;
bool Out_IsRadiusLogin; bool Out_IsRadiusLogin;
char NasId[RADIUS_MAX_NAS_ID_LEN + 1]; // NAS-Identifier char NasId[RADIUS_MAX_NAS_ID_LEN + 1]; // NAS-Identifier
char Out_VirtualMacAddress[6];
char In_VpnProtocolState[64];
}; };
// Function prototype // 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, 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 *RadiusEncryptPassword(char *password, UCHAR *random, UCHAR *secret, UINT secret_size);
BUF *RadiusCreateUserName(wchar_t *username); BUF *RadiusCreateUserName(wchar_t *username);
BUF *RadiusCreateUserPassword(void *data, UINT size); BUF *RadiusCreateUserPassword(void *data, UINT size);
BUF *RadiusCreateNasId(char *name); BUF *RadiusCreateNasId(char *name);
void RadiusAddValue(BUF *b, UCHAR t, UINT v, UCHAR vt, void *data, UINT size); void RadiusAddValue(BUF *b, UCHAR t, UINT v, UCHAR vt, void *data, UINT size);
LIST *RadiusParseOptions(BUF *b); LIST *RadiusParseOptions(BUF *b);
bool RadiusValidateAuthenticator(BUF *b, char *secret, char *request_authenticator, bool RadiusRequireMessageAuthenticator);
#endif // RADIUS_H #endif // RADIUS_H

@ -112,6 +112,10 @@ void EndRpc(RPC *rpc)
// Release the RPC // Release the RPC
void RpcFree(RPC *rpc) void RpcFree(RPC *rpc)
{
RpcFreeEx(rpc, false);
}
void RpcFreeEx(RPC *rpc, bool no_disconnect)
{ {
// Validate arguments // Validate arguments
if (rpc == NULL) if (rpc == NULL)
@ -119,7 +123,11 @@ void RpcFree(RPC *rpc)
return; return;
} }
if (no_disconnect == false)
{
Disconnect(rpc->Sock); Disconnect(rpc->Sock);
}
ReleaseSock(rpc->Sock); ReleaseSock(rpc->Sock);
DeleteLock(rpc->Lock); DeleteLock(rpc->Lock);

@ -139,6 +139,7 @@ bool RpcIsOk(PACK *p);
UINT RpcGetError(PACK *p); UINT RpcGetError(PACK *p);
void EndRpc(RPC *rpc); void EndRpc(RPC *rpc);
void RpcFree(RPC *rpc); void RpcFree(RPC *rpc);
void RpcFreeEx(RPC *rpc, bool no_disconnect);
#endif // REMOTE_H #endif // REMOTE_H

@ -3639,6 +3639,16 @@ void SmLicenseAddDlgOnOk(HWND hWnd, SM_SERVER *s)
{ {
RPC_TEST t; RPC_TEST t;
if (s->LicenseWarnFlag == false)
{
if (MsgBoxEx(hWnd, MB_ICONINFORMATION | MB_OKCANCEL, _UU("SM_LICENSE_WARNING")) == IDCANCEL)
{
return;
}
s->LicenseWarnFlag = true;
}
Disable(hWnd, IDOK); Disable(hWnd, IDOK);
Disable(hWnd, IDCANCEL); Disable(hWnd, IDCANCEL);
@ -8652,7 +8662,7 @@ void SmCreateCertDlgUpdate(HWND hWnd, SM_CERT *s)
} }
i = GetInt(hWnd, E_EXPIRE); i = GetInt(hWnd, E_EXPIRE);
if (i == 0 || i >= (365 * 30)) if (i == 0 || i >= 2920000)
{ {
ok = false; ok = false;
} }

@ -166,6 +166,7 @@ typedef struct SM_SERVER
bool VgsMessageDisplayed; // Whether to have already displayed a message about VGS bool VgsMessageDisplayed; // Whether to have already displayed a message about VGS
WINUI_UPDATE *Update; // Update notification WINUI_UPDATE *Update; // Update notification
bool IsInClient; // Within VPN Client mode bool IsInClient; // Within VPN Client mode
bool LicenseWarnFlag;
} SM_SERVER; } SM_SERVER;
typedef void (SM_STATUS_INIT_PROC)(HWND hWnd, SM_SERVER *p, void *param); typedef void (SM_STATUS_INIT_PROC)(HWND hWnd, SM_SERVER *p, void *param);

@ -954,6 +954,7 @@ UINT SwEasy2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, WIZARD *wizard,
case WM_COMMAND: case WM_COMMAND:
switch (wParam) switch (wParam)
{ {
case B_EASYMODE:
case B_DELETE_SENSITIVE: case B_DELETE_SENSITIVE:
sw->Easy_EraseSensitive = IsChecked(hWnd, B_DELETE_SENSITIVE); sw->Easy_EraseSensitive = IsChecked(hWnd, B_DELETE_SENSITIVE);
sw->Easy_EasyMode = IsChecked(hWnd, B_EASYMODE); sw->Easy_EasyMode = IsChecked(hWnd, B_EASYMODE);
@ -1051,6 +1052,7 @@ UINT SwWeb2(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, WIZARD *wizard, W
case WM_COMMAND: case WM_COMMAND:
switch (wParam) switch (wParam)
{ {
case B_EASYMODE:
case B_DELETE_SENSITIVE: case B_DELETE_SENSITIVE:
sw->Web_EraseSensitive = IsChecked(hWnd, B_DELETE_SENSITIVE); sw->Web_EraseSensitive = IsChecked(hWnd, B_DELETE_SENSITIVE);
sw->Web_EasyMode = IsChecked(hWnd, B_EASYMODE); sw->Web_EasyMode = IsChecked(hWnd, B_EASYMODE);
@ -5732,6 +5734,15 @@ UINT SwWelcomeDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, WIZARD *wiz
break; break;
} }
if (MsIsKB3033929RequiredAndMissing())
{
// KB3033929 is missing
if (MsgBoxEx(hWnd, MB_ICONINFORMATION | MB_OKCANCEL, _UU("SW_KB3033929_REQUIRED")) == IDCANCEL)
{
break;
}
}
if (sw->DoubleClickBlocker) if (sw->DoubleClickBlocker)
{ {
break; break;

@ -269,7 +269,7 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
// Attempt to login // Attempt to login
b = RadiusLogin(c, radius_server_addr, radius_server_port, b = RadiusLogin(c, radius_server_addr, radius_server_port,
radius_secret, StrLen(radius_secret), 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) if (b)
{ {

@ -845,12 +845,46 @@ LIST *SuGetAdapterList(SU *u)
for (i = 0;i < u->AdapterInfoList.NumAdapters;i++) for (i = 0;i < u->AdapterInfoList.NumAdapters;i++)
{ {
SL_ADAPTER_INFO *info = &u->AdapterInfoList.Adapters[i]; SL_ADAPTER_INFO *info = &u->AdapterInfoList.Adapters[i];
if (IsEmptyStr(info->FriendlyName))
{
// Some NetAdapterCx drivers doesn't report the FriendlyName in the kernel mode.
// So we attempt to obtain the DriverDesc string from NetCfg registry key alternatively.
char regkey[MAX_PATH] = {0};
char tmp[MAX_PATH] = {0};
char adapter_guid[MAX_PATH] = {0};
UniToStr(adapter_guid, sizeof(adapter_guid), info->AdapterId + StrLen(SL_ADAPTER_ID_PREFIX));
if (GetClassRegKeyWin32(regkey, sizeof(regkey), tmp, sizeof(tmp), adapter_guid))
{
char *driver_desc = MsRegReadStrEx2(REG_LOCAL_MACHINE, regkey, "DriverDesc", false, true);
if (driver_desc != NULL)
{
StrCpy(info->FriendlyName, sizeof(info->FriendlyName), driver_desc);
Free(driver_desc);
}
}
}
{
SU_ADAPTER_LIST *a = SuAdapterInfoToAdapterList(info); SU_ADAPTER_LIST *a = SuAdapterInfoToAdapterList(info);
char macstr[128] = {0};
BinToStr(macstr, sizeof(macstr), info->MacAddress, sizeof(info->MacAddress));
if (a != NULL) if (a != NULL)
{ {
// Debug("SU: Adapter %u (OK): ID=%S, MAC=%s, FriendlyName=%s\n", i, info->AdapterId, macstr, info->FriendlyName);
Add(ret, a); Add(ret, a);
} }
else
{
// Debug("SU: Adapter %u (NG): ID=%S, MAC=%s, FriendlyName=%s\n", i, info->AdapterId, macstr, info->FriendlyName);
}
}
} }
// Sort // Sort
@ -919,6 +953,7 @@ SU_ADAPTER_LIST *SuAdapterInfoToAdapterList(SL_ADAPTER_INFO *info)
Copy(&t.Info, info, sizeof(SL_ADAPTER_INFO)); Copy(&t.Info, info, sizeof(SL_ADAPTER_INFO));
UniToStr(tmp, sizeof(tmp), info->AdapterId); UniToStr(tmp, sizeof(tmp), info->AdapterId);
if (IsEmptyStr(tmp) || IsEmptyStr(info->FriendlyName) || StartWith(tmp, SL_ADAPTER_ID_PREFIX) == false) if (IsEmptyStr(tmp) || IsEmptyStr(info->FriendlyName) || StartWith(tmp, SL_ADAPTER_ID_PREFIX) == false)
{ {
// Name is invalid // Name is invalid

@ -1115,6 +1115,9 @@ LIST *EnumLogFile(char *hubname)
// Enumerate in the packet_log // Enumerate in the packet_log
Format(tmp, sizeof(tmp), "%s/packet_log", exe_dir); Format(tmp, sizeof(tmp), "%s/packet_log", exe_dir);
if (hubname == NULL)
{
dir = EnumDir(tmp); dir = EnumDir(tmp);
if (dir != NULL) if (dir != NULL)
{ {
@ -1127,19 +1130,29 @@ LIST *EnumLogFile(char *hubname)
{ {
char dir_name[MAX_PATH]; char dir_name[MAX_PATH];
if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0)
{
Format(dir_name, sizeof(dir_name), "packet_log/%s", e->FileName); Format(dir_name, sizeof(dir_name), "packet_log/%s", e->FileName);
EnumLogFileDir(o, dir_name); EnumLogFileDir(o, dir_name);
} }
} }
}
FreeDir(dir); FreeDir(dir);
} }
}
else
{
char dir_name[MAX_PATH];
Format(dir_name, sizeof(dir_name), "packet_log/%s", hubname);
EnumLogFileDir(o, dir_name);
}
// Enumerate in the security_log // Enumerate in the security_log
Format(tmp, sizeof(tmp), "%s/security_log", exe_dir); Format(tmp, sizeof(tmp), "%s/security_log", exe_dir);
if (hubname == NULL)
{
dir = EnumDir(tmp); dir = EnumDir(tmp);
if (dir != NULL) if (dir != NULL)
{ {
@ -1152,16 +1165,23 @@ LIST *EnumLogFile(char *hubname)
{ {
char dir_name[MAX_PATH]; char dir_name[MAX_PATH];
if (hubname == NULL || StrCmpi(hubname, e->FileName) == 0)
{
Format(dir_name, sizeof(dir_name), "security_log/%s", e->FileName); Format(dir_name, sizeof(dir_name), "security_log/%s", e->FileName);
EnumLogFileDir(o, dir_name); EnumLogFileDir(o, dir_name);
} }
} }
}
FreeDir(dir); FreeDir(dir);
} }
}
else
{
char dir_name[MAX_PATH];
Format(dir_name, sizeof(dir_name), "security_log/%s", hubname);
EnumLogFileDir(o, dir_name);
}
return o; return o;
} }
@ -1255,9 +1275,14 @@ UINT GetServerCapsInt(SERVER *s, char *name)
} }
Zero(&t, sizeof(t)); Zero(&t, sizeof(t));
Lock(s->CapsCacheLock);
{
GetServerCaps(s, &t); GetServerCaps(s, &t);
ret = GetCapsInt(&t, name); ret = GetCapsInt(&t, name);
}
Unlock(s->CapsCacheLock);
return ret; return ret;
} }
@ -1326,10 +1351,14 @@ void FlushServerCaps(SERVER *s)
return; return;
} }
Lock(s->CapsCacheLock);
{
DestroyServerCapsCache(s); DestroyServerCapsCache(s);
Zero(&t, sizeof(t)); Zero(&t, sizeof(t));
GetServerCaps(s, &t); GetServerCaps(s, &t);
}
Unlock(s->CapsCacheLock);
} }
// Get the Caps list for this server // Get the Caps list for this server
@ -1871,14 +1900,37 @@ void OutRpcCapsList(PACK *p, CAPSLIST *t)
return; return;
} }
PackSetCurrentJsonGroupName(p, "CapsList");
for (i = 0;i < LIST_NUM(t->CapsList);i++) for (i = 0;i < LIST_NUM(t->CapsList);i++)
{ {
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
char ct_key[MAX_PATH];
wchar_t ct_description[MAX_PATH];
wchar_t *w;
CAPS *c = LIST_DATA(t->CapsList, i); CAPS *c = LIST_DATA(t->CapsList, i);
Format(tmp, sizeof(tmp), "caps_%s", c->Name); Format(tmp, sizeof(tmp), "caps_%s", c->Name);
PackAddInt(p, tmp, c->Value);
Format(ct_key, sizeof(ct_key), "CT_%s", c->Name);
Zero(ct_description, sizeof(ct_description));
w = _UU(ct_key);
if (UniIsEmptyStr(w) == false)
{
UniStrCpy(ct_description, sizeof(ct_description), w);
} }
else
{
StrToUni(ct_description, sizeof(ct_description), c->Name);
}
PackAddInt(p, tmp, c->Value);
PackAddStrEx(p, "CapsName", c->Name, i, LIST_NUM(t->CapsList));
PackAddIntEx(p, "CapsValue", c->Value, i, LIST_NUM(t->CapsList));
PackAddUniStrEx(p, "CapsDescrption", ct_description, i, LIST_NUM(t->CapsList));
}
PackSetCurrentJsonGroupName(p, NULL);
} }
void FreeRpcCapsList(CAPSLIST *t) void FreeRpcCapsList(CAPSLIST *t)
{ {
@ -5008,6 +5060,7 @@ void SiWriteHubCfg(FOLDER *f, HUB *h)
CfgAddBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap", h->RadiusConvertAllMsChapv2AuthRequestToEap); CfgAddBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap", h->RadiusConvertAllMsChapv2AuthRequestToEap);
CfgAddBool(f, "RadiusUsePeapInsteadOfEap", h->RadiusUsePeapInsteadOfEap); CfgAddBool(f, "RadiusUsePeapInsteadOfEap", h->RadiusUsePeapInsteadOfEap);
CfgAddBool(f, "RadiusRequireMessageAuthenticator", h->RadiusRequireMessageAuthenticator);
} }
Unlock(h->RadiusOptionLock); Unlock(h->RadiusOptionLock);
@ -5177,6 +5230,7 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
h->RadiusConvertAllMsChapv2AuthRequestToEap = CfgGetBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap"); h->RadiusConvertAllMsChapv2AuthRequestToEap = CfgGetBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap");
h->RadiusUsePeapInsteadOfEap = CfgGetBool(f, "RadiusUsePeapInsteadOfEap"); h->RadiusUsePeapInsteadOfEap = CfgGetBool(f, "RadiusUsePeapInsteadOfEap");
h->RadiusRequireMessageAuthenticator = CfgGetBool(f, "RadiusRequireMessageAuthenticator");
if (interval == 0) if (interval == 0)
{ {
@ -5960,6 +6014,9 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
// Disable the NAT-traversal feature // Disable the NAT-traversal feature
s->DisableNatTraversal = CfgGetBool(f, "DisableNatTraversal"); s->DisableNatTraversal = CfgGetBool(f, "DisableNatTraversal");
// Disable IPsec Aggressive Mode
s->DisableIPsecAggressiveMode = CfgGetBool(f, "DisableIPsecAggressiveMode");
// Intel AES // Intel AES
s->DisableIntelAesAcceleration = CfgGetBool(f, "DisableIntelAesAcceleration"); s->DisableIntelAesAcceleration = CfgGetBool(f, "DisableIntelAesAcceleration");
@ -6165,8 +6222,12 @@ void SiLoadServerCfg(SERVER *s, FOLDER *f)
c->SslAcceptSettings.Tls_Disable1_0 = CfgGetBool(f, "Tls_Disable1_0"); c->SslAcceptSettings.Tls_Disable1_0 = CfgGetBool(f, "Tls_Disable1_0");
c->SslAcceptSettings.Tls_Disable1_1 = CfgGetBool(f, "Tls_Disable1_1"); c->SslAcceptSettings.Tls_Disable1_1 = CfgGetBool(f, "Tls_Disable1_1");
c->SslAcceptSettings.Tls_Disable1_2 = CfgGetBool(f, "Tls_Disable1_2"); c->SslAcceptSettings.Tls_Disable1_2 = CfgGetBool(f, "Tls_Disable1_2");
c->SslAcceptSettings.Tls_Disable1_3 = CfgGetBool(f, "Tls_Disable1_3");
s->StrictSyslogDatetimeFormat = CfgGetBool(f, "StrictSyslogDatetimeFormat"); s->StrictSyslogDatetimeFormat = CfgGetBool(f, "StrictSyslogDatetimeFormat");
// Disable JSON-RPC Web API
s->DisableJsonRpcWebApi = CfgGetBool(f, "DisableJsonRpcWebApi");
} }
Unlock(c->lock); Unlock(c->lock);
@ -6364,6 +6425,8 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s)
} }
} }
CfgAddBool(f, "DisableIPsecAggressiveMode", s->DisableIPsecAggressiveMode);
CfgAddStr(f, "OpenVPNDefaultClientOption", c->OpenVPNDefaultClientOption); CfgAddStr(f, "OpenVPNDefaultClientOption", c->OpenVPNDefaultClientOption);
if (c->Bridge == false) if (c->Bridge == false)
@ -6479,11 +6542,15 @@ void SiWriteServerCfg(FOLDER *f, SERVER *s)
CfgAddBool(f, "Tls_Disable1_0", c->SslAcceptSettings.Tls_Disable1_0); CfgAddBool(f, "Tls_Disable1_0", c->SslAcceptSettings.Tls_Disable1_0);
CfgAddBool(f, "Tls_Disable1_1", c->SslAcceptSettings.Tls_Disable1_1); CfgAddBool(f, "Tls_Disable1_1", c->SslAcceptSettings.Tls_Disable1_1);
CfgAddBool(f, "Tls_Disable1_2", c->SslAcceptSettings.Tls_Disable1_2); CfgAddBool(f, "Tls_Disable1_2", c->SslAcceptSettings.Tls_Disable1_2);
CfgAddBool(f, "Tls_Disable1_3", c->SslAcceptSettings.Tls_Disable1_3);
// Disable session reconnect // Disable session reconnect
CfgAddBool(f, "DisableSessionReconnect", GetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT)); CfgAddBool(f, "DisableSessionReconnect", GetGlobalServerFlag(GSF_DISABLE_SESSION_RECONNECT));
CfgAddBool(f, "StrictSyslogDatetimeFormat", s->StrictSyslogDatetimeFormat); CfgAddBool(f, "StrictSyslogDatetimeFormat", s->StrictSyslogDatetimeFormat);
// Disable JSON-RPC Web API
CfgAddBool(f, "DisableJsonRpcWebApi", s->DisableJsonRpcWebApi);
} }
Unlock(c->lock); Unlock(c->lock);
} }
@ -7211,7 +7278,7 @@ FARM_MEMBER *SiGetNextFarmMember(SERVER *s, CONNECTION *c, HUB *h)
PackAddIntEx(p, "NumTcpConnections", f->NumTcpConnections, i, num); PackAddIntEx(p, "NumTcpConnections", f->NumTcpConnections, i, num);
PackAddIntEx(p, "NumHubs", LIST_NUM(f->HubList), i, num); PackAddIntEx(p, "NumHubs", LIST_NUM(f->HubList), i, num);
PackAddBoolEx(p, "Me", f->Me, i, num); PackAddBoolEx(p, "Me", f->Me, i, num);
PackAddInt64Ex(p, "ConnectedTime", f->ConnectedTime, i, num); PackAddTime64Ex(p, "ConnectedTime", f->ConnectedTime, i, num);
PackAddInt64Ex(p, "SystemId", f->SystemId, i, num); PackAddInt64Ex(p, "SystemId", f->SystemId, i, num);
PackAddBoolEx(p, "DoNotSelect", do_not_select, i, num); PackAddBoolEx(p, "DoNotSelect", do_not_select, i, num);
} }
@ -7240,7 +7307,7 @@ FARM_MEMBER *SiGetNextFarmMember(SERVER *s, CONNECTION *c, HUB *h)
PackAddStr(p, "CipherName", c->CipherName); PackAddStr(p, "CipherName", c->CipherName);
PackAddStr(p, "ClientStr", c->ClientStr); PackAddStr(p, "ClientStr", c->ClientStr);
PackAddInt(p, "ClientVer", c->ClientVer); PackAddInt(p, "ClientVer", c->ClientVer);
PackAddInt64(p, "ConnectedTime", Tick64ToTime64(c->ConnectedTick)); PackAddTime64(p, "ConnectedTime", Tick64ToTime64(c->ConnectedTick));
PackAddStr(p, "HubName", h->Name); PackAddStr(p, "HubName", h->Name);
PackAddBool(p, "StaticHub", h->Type == HUB_TYPE_FARM_STATIC); PackAddBool(p, "StaticHub", h->Type == HUB_TYPE_FARM_STATIC);
@ -7381,8 +7448,8 @@ void SiCalledEnumHub(SERVER *s, PACK *p, PACK *req)
PackAddIntEx(p, "NumIpTables", LIST_NUM(h->IpTable), i, num); PackAddIntEx(p, "NumIpTables", LIST_NUM(h->IpTable), i, num);
PackAddInt64Ex(p, "LastCommTime", h->LastCommTime, i, num); PackAddTime64Ex(p, "LastCommTime", h->LastCommTime, i, num);
PackAddInt64Ex(p, "CreatedTime", h->CreatedTime, i, num); PackAddTime64Ex(p, "CreatedTime", h->CreatedTime, i, num);
} }
Unlock(h->lock); Unlock(h->lock);
} }
@ -7775,7 +7842,7 @@ void SiCalledDeleteIpTable(SERVER *s, PACK *p)
return; return;
} }
LockList(h->IpTable); LockHashList(h->MacHashTable);
{ {
if (IsInList(h->IpTable, (void *)key)) if (IsInList(h->IpTable, (void *)key))
{ {
@ -7784,7 +7851,7 @@ void SiCalledDeleteIpTable(SERVER *s, PACK *p)
Free(e); Free(e);
} }
} }
UnlockList(h->IpTable); UnlockHashList(h->MacHashTable);
ReleaseHub(h); ReleaseHub(h);
} }
@ -8587,14 +8654,9 @@ void SiCallEnumHub(SERVER *s, FARM_MEMBER *f)
LockHashList(h->MacHashTable); LockHashList(h->MacHashTable);
{ {
hh->NumMacTables = HASH_LIST_NUM(h->MacHashTable); hh->NumMacTables = HASH_LIST_NUM(h->MacHashTable);
}
UnlockHashList(h->MacHashTable);
LockList(h->IpTable);
{
hh->NumIpTables = LIST_NUM(h->IpTable); hh->NumIpTables = LIST_NUM(h->IpTable);
} }
UnlockList(h->IpTable); UnlockHashList(h->MacHashTable);
} }
} }
} }
@ -10309,12 +10371,16 @@ void SiFarmServMain(SERVER *server, SOCK *sock, FARM_MEMBER *f)
} }
// Receive // Receive
p = HttpServerRecv(sock); p = HttpServerRecvEx(sock, FIRM_SERV_RECV_PACK_MAX_SIZE);
t->Response = p; t->Response = p;
Set(t->CompleteEvent); Set(t->CompleteEvent);
send_noop = false; if (p == NULL)
{
Disconnect(sock);
goto DISCONNECTED;
}
} }
} }
while (t != NULL); while (t != NULL);

@ -147,6 +147,8 @@ extern char *SERVER_CONFIG_FILE_NAME;
#define MEMBER_SELECTOR_CONNECT_TIMEOUT 2000 #define MEMBER_SELECTOR_CONNECT_TIMEOUT 2000
#define MEMBER_SELECTOR_DATA_TIMEOUT 5000 #define MEMBER_SELECTOR_DATA_TIMEOUT 5000
#define FIRM_SERV_RECV_PACK_MAX_SIZE (100 * 1024 * 1024)
// Virtual HUB list hosted by each farm member // Virtual HUB list hosted by each farm member
struct HUB_LIST struct HUB_LIST
@ -286,6 +288,7 @@ struct SERVER
bool NoMoreSave; // Do not save any more bool NoMoreSave; // Do not save any more
bool EnableConditionalAccept; // Apply the Conditional Accept the Listener bool EnableConditionalAccept; // Apply the Conditional Accept the Listener
bool EnableLegacySSL; // Enable Legacy SSL bool EnableLegacySSL; // Enable Legacy SSL
bool DisableIPsecAggressiveMode; // Disable IPsec Aggressive Mode
volatile bool Halt; // Halting flag volatile bool Halt; // Halting flag
LOCK *lock; // Lock LOCK *lock; // Lock
@ -360,6 +363,7 @@ struct SERVER
volatile UINT NatTGlobalUdpPort; // NAT-T global UDP port volatile UINT NatTGlobalUdpPort; // NAT-T global UDP port
bool StrictSyslogDatetimeFormat; // Make syslog datetime format strict RFC3164 bool StrictSyslogDatetimeFormat; // Make syslog datetime format strict RFC3164
bool DisableJsonRpcWebApi; // Disable JSON-RPC Web API
}; };
@ -383,6 +387,7 @@ struct RPC_SESSION_STATUS
RPC_CLIENT_GET_CONNECTION_STATUS Status; // Status RPC_CLIENT_GET_CONNECTION_STATUS Status; // Status
UINT ClientIp; // Client IP address UINT ClientIp; // Client IP address
UCHAR ClientIp6[16]; // Client IPv6 address UCHAR ClientIp6[16]; // Client IPv6 address
IP ClientIpAddress; // Client IP address (IPv4/IPv6)
char ClientHostName[MAX_HOST_NAME_LEN + 1]; // Client host name char ClientHostName[MAX_HOST_NAME_LEN + 1]; // Client host name
NODE_INFO NodeInfo; // Node information NODE_INFO NodeInfo; // Node information
}; };

@ -1257,7 +1257,10 @@ void StopSessionEx(SESSION *s, bool no_wait)
// Client mode // Client mode
if (s->Connection) if (s->Connection)
{ {
StopConnection(s->Connection, no_wait); CONNECTION *c = s->Connection;
AddRef(c->ref);
StopConnection(c, no_wait);
ReleaseConnection(c);
} }
} }
else else
@ -1265,7 +1268,10 @@ void StopSessionEx(SESSION *s, bool no_wait)
// Server mode // Server mode
if (s->Connection) if (s->Connection)
{ {
StopConnection(s->Connection, no_wait); CONNECTION *c = s->Connection;
AddRef(c->ref);
StopConnection(c, no_wait);
ReleaseConnection(c);
} }
} }
@ -1391,6 +1397,9 @@ void CleanupSession(SESSION *s)
DeleteCounter(s->LoggingRecordCount); DeleteCounter(s->LoggingRecordCount);
ReleaseSharedBuffer(s->IpcSessionSharedBuffer);
Free(s); Free(s);
} }
@ -1721,7 +1730,13 @@ void ClientThread(THREAD *t, void *param)
StrCpy(p.ServerName, sizeof(p.ServerName), s->ClientOption->Hostname); StrCpy(p.ServerName, sizeof(p.ServerName), s->ClientOption->Hostname);
} }
if(s->CurrentRetryCount < s->ClientOption->NumRetry){
p.RetryIntervalSec = s->RetryInterval / 1000; p.RetryIntervalSec = s->RetryInterval / 1000;
}else{
// Disable the retry timeout if retries exceeds the limit
p.RetryIntervalSec = 0;
}
p.Type = s->ClientAuth->AuthType; p.Type = s->ClientAuth->AuthType;
// Display the password re-entry dialog // Display the password re-entry dialog
@ -2199,9 +2214,9 @@ void if_free(SESSION *s);
// Create a server session // Create a server session
SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy) SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy)
{ {
return NewServerSessionEx(cedar, c, h, username, policy, false); return NewServerSessionEx(cedar, c, h, username, policy, false, NULL);
} }
SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode) SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode, UCHAR *ipc_mac_address)
{ {
SESSION *s; SESSION *s;
char name[MAX_SIZE]; char name[MAX_SIZE];
@ -2321,6 +2336,12 @@ SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username,
// Generate a MAC address for IPC // Generate a MAC address for IPC
if (s->InProcMode) if (s->InProcMode)
{
if (ipc_mac_address != NULL)
{
Copy(s->IpcMacAddress, ipc_mac_address, 6);
}
else
{ {
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
char machine[MAX_SIZE]; char machine[MAX_SIZE];
@ -2345,6 +2366,8 @@ SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username,
MacToStr(tmp, sizeof(tmp), s->IpcMacAddress); MacToStr(tmp, sizeof(tmp), s->IpcMacAddress);
Debug("MAC Address for IPC: %s\n", tmp); Debug("MAC Address for IPC: %s\n", tmp);
} }
}
return s; return s;
} }

@ -185,6 +185,7 @@ struct SESSION
THREAD *Thread; // Management thread THREAD *Thread; // Management thread
CONNECTION *Connection; // Connection CONNECTION *Connection; // Connection
char ClientIP[64]; // Client IP char ClientIP[64]; // Client IP
UINT ClientPort; // Client Port
CLIENT_OPTION *ClientOption; // Client connection options CLIENT_OPTION *ClientOption; // Client connection options
CLIENT_AUTH *ClientAuth; // Client authentication data CLIENT_AUTH *ClientAuth; // Client authentication data
volatile bool Halt; // Halting flag volatile bool Halt; // Halting flag
@ -256,6 +257,7 @@ struct SESSION
UINT NumDisconnected; // Number of socket disconnection UINT NumDisconnected; // Number of socket disconnection
bool NoReconnectToSession; // Disable to reconnect to the session bool NoReconnectToSession; // Disable to reconnect to the session
char UnderlayProtocol[64]; // Physical communication protocol char UnderlayProtocol[64]; // Physical communication protocol
char ProtocolDetails[256]; // Protocol Details
UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection UINT64 FirstConnectionEstablisiedTime; // Connection completion time of the first connection
UINT64 CurrentConnectionEstablishTime; // Completion time of this connection UINT64 CurrentConnectionEstablishTime; // Completion time of this connection
UINT NumConnectionsEatablished; // Number of connections established so far UINT NumConnectionsEatablished; // Number of connections established so far
@ -265,10 +267,12 @@ struct SESSION
bool IsRUDPSession; // Whether R-UDP session bool IsRUDPSession; // Whether R-UDP session
UINT RUdpMss; // The value of the MSS should be applied while the R-UDP is used UINT RUdpMss; // The value of the MSS should be applied while the R-UDP is used
bool EnableBulkOnRUDP; // Allow the bulk transfer in the R-UDP session bool EnableBulkOnRUDP; // Allow the bulk transfer in the R-UDP session
UINT BulkOnRUDPVersion; // RUDP Bulk Version
bool EnableHMacOnBulkOfRUDP; // Use the HMAC to sign the bulk transfer of R-UDP session bool EnableHMacOnBulkOfRUDP; // Use the HMAC to sign the bulk transfer of R-UDP session
bool EnableUdpRecovery; // Enable the R-UDP recovery bool EnableUdpRecovery; // Enable the R-UDP recovery
bool UseUdpAcceleration; // Use of UDP acceleration mode bool UseUdpAcceleration; // Use of UDP acceleration mode
UINT UdpAccelerationVersion; // UDP acceleration version
bool UseHMacOnUdpAcceleration; // Use the HMAC in the UDP acceleration mode bool UseHMacOnUdpAcceleration; // Use the HMAC in the UDP acceleration mode
UDP_ACCEL *UdpAccel; // UDP acceleration UDP_ACCEL *UdpAccel; // UDP acceleration
bool IsUsingUdpAcceleration; // Flag of whether the UDP acceleration is used bool IsUsingUdpAcceleration; // Flag of whether the UDP acceleration is used
@ -308,6 +312,11 @@ struct SESSION
char FirstTimeHttpRedirectUrl[128]; // URL for redirection only the first time char FirstTimeHttpRedirectUrl[128]; // URL for redirection only the first time
UINT FirstTimeHttpAccessCheckIp; // IP address for access checking UINT FirstTimeHttpAccessCheckIp; // IP address for access checking
UCHAR BulkSendKey[RUDP_BULK_KEY_SIZE_MAX]; // RUDP Bulk Send Key
UINT BulkSendKeySize; // RUDP Bulk Send Key size
UCHAR BulkRecvKey[RUDP_BULK_KEY_SIZE_MAX]; // RUDP Bulk Recv Key
UINT BulkRecvKeySize; // RUDP Bulk Recv Key size
// To examine the maximum number of alowed logging target packets per minute // To examine the maximum number of alowed logging target packets per minute
UINT64 MaxLoggedPacketsPerMinuteStartTick; // Inspection start time UINT64 MaxLoggedPacketsPerMinuteStartTick; // Inspection start time
UINT CurrentNumPackets; // Current number of packets UINT CurrentNumPackets; // Current number of packets
@ -315,6 +324,15 @@ struct SESSION
// Measures for D-Link bug // Measures for D-Link bug
UINT64 LastDLinkSTPPacketSendTick; // Last D-Link STP packet transmission time UINT64 LastDLinkSTPPacketSendTick; // Last D-Link STP packet transmission time
UCHAR LastDLinkSTPPacketDataHash[MD5_SIZE]; // Last D-Link STP packet hash UCHAR LastDLinkSTPPacketDataHash[MD5_SIZE]; // Last D-Link STP packet hash
SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session
IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // A shared data between IPC and Session
bool EnableLightRecvFilter; // Enable light receive filter
UINT LightRecvFilterMac; // Light receive filter MAC address
UINT LightRecvFilterIPv4_1; // Light receive filter IPv4 address #1
UINT LightRecvFilterIPv4_2; // Light receive filter IPv4 address #2
}; };
// Password dialog // Password dialog
@ -396,7 +414,7 @@ SESSION *NewRpcSession(CEDAR *cedar, CLIENT_OPTION *option);
SESSION *NewRpcSessionEx(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str); SESSION *NewRpcSessionEx(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str);
SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str, void *hWnd); SESSION *NewRpcSessionEx2(CEDAR *cedar, CLIENT_OPTION *option, UINT *err, char *client_str, void *hWnd);
SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy); SESSION *NewServerSession(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy);
SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode); SESSION *NewServerSessionEx(CEDAR *cedar, CONNECTION *c, HUB *h, char *username, POLICY *policy, bool inproc_mode, UCHAR *ipc_mac_address);
void ClientThread(THREAD *t, void *param); void ClientThread(THREAD *t, void *param);
void ReleaseSession(SESSION *s); void ReleaseSession(SESSION *s);
void CleanupSession(SESSION *s); void CleanupSession(SESSION *s);

@ -350,7 +350,7 @@ void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b)
return; return;
} }
UdpAccelSend(a, b->Buf, b->Size, b->Compressed, a->MaxUdpPacketSize, b->PriorityQoS); UdpAccelSend(a, b->Buf, b->Size, b->Compressed ? 1 : 0, a->MaxUdpPacketSize, b->PriorityQoS);
} }
// Calculate the best MSS // Calculate the best MSS
@ -382,7 +382,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
// IV // IV
ret -= UDP_ACCELERATION_PACKET_IV_SIZE; ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
} }
// Cookie // Cookie
@ -403,7 +403,7 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
// Verify // Verify
ret -= UDP_ACCELERATION_PACKET_IV_SIZE; ret -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
} }
// Ethernet header (communication packets) // Ethernet header (communication packets)
@ -419,12 +419,12 @@ UINT UdpAccelCalcMss(UDP_ACCEL *a)
} }
// Send // Send
void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority) void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority)
{ {
UCHAR tmp[UDP_ACCELERATION_TMP_BUF_SIZE]; UCHAR tmp[UDP_ACCELERATION_TMP_BUF_SIZE];
UCHAR *buf; UCHAR *buf;
UINT size; UINT size;
UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE]; UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
UINT64 ui64; UINT64 ui64;
USHORT us; USHORT us;
UCHAR c; UCHAR c;
@ -448,11 +448,23 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
// IV // IV
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
if (a->Version == 2)
{
// Version 2.0
// IV // IV
Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE); Copy(buf, a->NextIv_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
buf += UDP_ACCELERATION_PACKET_IV_SIZE; buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
size += UDP_ACCELERATION_PACKET_IV_SIZE; size += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
}
else
{
// Version 1.0
// IV
Copy(buf, a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
// Calculate the key // Calculate the key
UdpAccelCalcKey(key, a->MyKey, a->NextIv); UdpAccelCalcKey(key, a->MyKey, a->NextIv);
@ -463,7 +475,7 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
char tmp2[256]; char tmp2[256];
char tmp3[256]; char tmp3[256];
BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey)); BinToStr(tmp1, sizeof(tmp1), a->MyKey, sizeof(a->MyKey));
BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE); BinToStr(tmp2, sizeof(tmp2), a->NextIv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
Debug("My Key : %s\n" Debug("My Key : %s\n"
"IV : %s\n" "IV : %s\n"
@ -471,6 +483,7 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
tmp1, tmp2, tmp3); tmp1, tmp2, tmp3);
} }
} }
}
// Cookie // Cookie
ui32 = Endian32(a->YourCookie); ui32 = Endian32(a->YourCookie);
@ -496,8 +509,8 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
buf += sizeof(USHORT); buf += sizeof(USHORT);
size += sizeof(USHORT); size += sizeof(USHORT);
// Compress Flag // Flag
c = (compressed ? 1 : 0); c = flag;
Copy(buf, &c, sizeof(UCHAR)); Copy(buf, &c, sizeof(UCHAR));
buf += sizeof(UCHAR); buf += sizeof(UCHAR);
size += sizeof(UCHAR); size += sizeof(UCHAR);
@ -512,11 +525,47 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE] = {0}; if (a->Version == 2)
{
// Ver 2
// Padding
current_size = UDP_ACCELERATION_PACKET_IV_SIZE_V2 + sizeof(UINT) + sizeof(UINT64) * 2 +
sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
if (current_size < max_size)
{
UCHAR pad[UDP_ACCELERATION_MAX_PADDING_SIZE];
UINT pad_size = MIN(max_size - current_size, UDP_ACCELERATION_MAX_PADDING_SIZE);
pad_size = rand() % pad_size;
Zero(pad, sizeof(pad));
Copy(buf, pad, pad_size);
buf += pad_size;
size += pad_size;
}
// Encryption by RFC 8439: ChaCha20-Poly1305-IETF Encryption with AEAD
Aead_ChaCha20Poly1305_Ietf_Encrypt(tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2,
tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2,
size - UDP_ACCELERATION_PACKET_IV_SIZE_V2,
a->MyKey_V2,
a->NextIv_V2,
NULL, 0);
// Next Iv
Copy(a->NextIv_V2,
tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V2 + size - UDP_ACCELERATION_PACKET_IV_SIZE_V2 - UDP_ACCELERATION_PACKET_IV_SIZE_V2, UDP_ACCELERATION_PACKET_IV_SIZE_V2);
// MAC
size += UDP_ACCELERATION_PACKET_MAC_SIZE_V2;
}
else
{
// Ver 1
static UCHAR zero[UDP_ACCELERATION_PACKET_IV_SIZE_V1] = {0};
CRYPT *c; CRYPT *c;
current_size = UDP_ACCELERATION_PACKET_IV_SIZE + sizeof(UINT) + sizeof(UINT64) * 2 + current_size = UDP_ACCELERATION_PACKET_IV_SIZE_V1 + sizeof(UINT) + sizeof(UINT64) * 2 +
sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE; sizeof(USHORT) + sizeof(UCHAR) + data_size + UDP_ACCELERATION_PACKET_IV_SIZE_V1;
if (current_size < max_size) if (current_size < max_size)
{ {
@ -532,17 +581,18 @@ void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UI
} }
// Verify // Verify
Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE); Copy(buf, zero, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
buf += UDP_ACCELERATION_PACKET_IV_SIZE; buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
size += UDP_ACCELERATION_PACKET_IV_SIZE; size += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
// Encryption // Encryption
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, tmp + UDP_ACCELERATION_PACKET_IV_SIZE, size - UDP_ACCELERATION_PACKET_IV_SIZE); Encrypt(c, tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V1, tmp + UDP_ACCELERATION_PACKET_IV_SIZE_V1, size - UDP_ACCELERATION_PACKET_IV_SIZE_V1);
FreeCrypt(c); FreeCrypt(c);
// Next Iv // Next Iv
Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE, UDP_ACCELERATION_PACKET_IV_SIZE); Copy(a->NextIv, buf - UDP_ACCELERATION_PACKET_IV_SIZE_V1, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
}
} }
// Send // Send
@ -667,7 +717,7 @@ bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive)
// Process the received packet // Process the received packet
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port) BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port)
{ {
UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE]; UCHAR key[UDP_ACCELERATION_PACKET_KEY_SIZE_V1];
UCHAR *iv; UCHAR *iv;
CRYPT *c; CRYPT *c;
UINT64 my_tick, your_tick; UINT64 my_tick, your_tick;
@ -676,6 +726,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
UINT pad_size; UINT pad_size;
UCHAR *verify; UCHAR *verify;
bool compress_flag; bool compress_flag;
UCHAR raw_flag;
BLOCK *b = NULL; BLOCK *b = NULL;
UINT cookie; UINT cookie;
// Validate arguments // Validate arguments
@ -686,14 +737,43 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{ {
if (a->Version == 2)
{
// Version 2.0
// IV // IV
if (size < UDP_ACCELERATION_PACKET_IV_SIZE) if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V2)
{ {
return NULL; return NULL;
} }
iv = buf; iv = buf;
buf += UDP_ACCELERATION_PACKET_IV_SIZE; buf += UDP_ACCELERATION_PACKET_IV_SIZE_V2;
size -= UDP_ACCELERATION_PACKET_IV_SIZE; size -= UDP_ACCELERATION_PACKET_IV_SIZE_V2;
if (size < AEAD_CHACHA20_POLY1305_MAC_SIZE)
{
return NULL;
}
// Decryption by RFC 8439: ChaCha20-Poly1305-IETF Encryption with AEAD
if (Aead_ChaCha20Poly1305_Ietf_Decrypt(buf, buf, size, a->YourKey_V2,
iv, NULL, 0) == false)
{
return NULL;
}
size -= AEAD_CHACHA20_POLY1305_MAC_SIZE;
}
else
{
// Version 1.0
// IV
if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
{
return NULL;
}
iv = buf;
buf += UDP_ACCELERATION_PACKET_IV_SIZE_V1;
size -= UDP_ACCELERATION_PACKET_IV_SIZE_V1;
// Calculate the key // Calculate the key
UdpAccelCalcKey(key, a->YourKey, iv); UdpAccelCalcKey(key, a->YourKey, iv);
@ -704,7 +784,7 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
char tmp2[256]; char tmp2[256];
char tmp3[256]; char tmp3[256];
BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey)); BinToStr(tmp1, sizeof(tmp1), a->YourKey, sizeof(a->YourKey));
BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE); BinToStr(tmp2, sizeof(tmp2), iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
BinToStr(tmp3, sizeof(tmp3), key, sizeof(key)); BinToStr(tmp3, sizeof(tmp3), key, sizeof(key));
Debug("Your Key: %s\n" Debug("Your Key: %s\n"
"IV : %s\n" "IV : %s\n"
@ -713,10 +793,11 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
} }
// Decryption // Decryption
c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE); c = NewCrypt(key, UDP_ACCELERATION_PACKET_KEY_SIZE_V1);
Encrypt(c, buf, buf, size); Encrypt(c, buf, buf, size);
FreeCrypt(c); FreeCrypt(c);
} }
}
// Cookie // Cookie
if (size < sizeof(UINT)) if (size < sizeof(UINT))
@ -759,12 +840,20 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
buf += sizeof(USHORT); buf += sizeof(USHORT);
size -= sizeof(USHORT); size -= sizeof(USHORT);
// compress_flag // flag
if (size < sizeof(UCHAR)) if (size < sizeof(UCHAR))
{ {
return NULL; return NULL;
} }
if (a->ReadRawFlagMode == false)
{
compress_flag = *((UCHAR *)buf); compress_flag = *((UCHAR *)buf);
}
else
{
raw_flag = *((UCHAR *)buf);
}
buf += sizeof(UCHAR); buf += sizeof(UCHAR);
size -= sizeof(UCHAR); size -= sizeof(UCHAR);
@ -782,29 +871,32 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
} }
if (a->PlainTextMode == false) if (a->PlainTextMode == false)
{
if (a->Version == 1)
{ {
// padding // padding
if (size < UDP_ACCELERATION_PACKET_IV_SIZE) if (size < UDP_ACCELERATION_PACKET_IV_SIZE_V1)
{ {
return false; return false;
} }
pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE; pad_size = size - UDP_ACCELERATION_PACKET_IV_SIZE_V1;
buf += pad_size; buf += pad_size;
size -= pad_size; size -= pad_size;
// verify // verify
if (size != UDP_ACCELERATION_PACKET_IV_SIZE) if (size != UDP_ACCELERATION_PACKET_IV_SIZE_V1)
{ {
return NULL; return NULL;
} }
verify = buf; verify = buf;
if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE) == false) if (IsZero(verify, UDP_ACCELERATION_PACKET_IV_SIZE_V1) == false)
{ {
return NULL; return NULL;
} }
} }
}
if (my_tick < a->LastRecvYourTick) if (my_tick < a->LastRecvYourTick)
{ {
@ -819,7 +911,11 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
if (inner_size >= 1) if (inner_size >= 1)
{ {
b = NewBlock(Clone(inner_data, inner_size), inner_size, compress_flag ? -1 : 0); b = NewBlock(Clone(inner_data, inner_size), inner_size, a->ReadRawFlagMode == false ? (compress_flag ? -1 : 0) : 0);
if (a->ReadRawFlagMode)
{
b->RawFlagRetUdpAccel = raw_flag;
}
} }
if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick) if (a->LastSetSrcIpAndPortTick < a->LastRecvYourTick)
@ -851,15 +947,15 @@ BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip
// Calculate the key // Calculate the key
void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv) void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv)
{ {
UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE + UDP_ACCELERATION_PACKET_IV_SIZE]; UCHAR tmp[UDP_ACCELERATION_COMMON_KEY_SIZE_V1 + UDP_ACCELERATION_PACKET_IV_SIZE_V1];
// Validate arguments // Validate arguments
if (key == NULL || common_key == NULL || iv == NULL) if (key == NULL || common_key == NULL || iv == NULL)
{ {
return; return;
} }
Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE); Copy(tmp, common_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE, iv, UDP_ACCELERATION_PACKET_IV_SIZE); Copy(tmp + UDP_ACCELERATION_COMMON_KEY_SIZE_V1, iv, UDP_ACCELERATION_PACKET_IV_SIZE_V1);
HashSha1(key, tmp, sizeof(tmp)); HashSha1(key, tmp, sizeof(tmp));
} }
@ -887,7 +983,9 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
} }
IPToStr(tmp, sizeof(tmp), client_ip); IPToStr(tmp, sizeof(tmp), client_ip);
Debug("UdpAccelInitServer: client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, client_port, Debug("UdpAccelInitServer: ver=%u, client_ip=%s, client_port=%u, server_cookie=%u, client_cookie=%u\n",
a->Version,
tmp, client_port,
a->MyCookie, a->YourCookie); a->MyCookie, a->YourCookie);
if (IsIP6(client_ip) != a->IsIPv6) if (IsIP6(client_ip) != a->IsIPv6)
@ -895,7 +993,14 @@ bool UdpAccelInitServer(UDP_ACCEL *a, UCHAR *client_key, IP *client_ip, UINT cli
return false; return false;
} }
Copy(a->YourKey, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE); if (a->Version == 2)
{
Copy(a->YourKey_V2, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
}
else
{
Copy(a->YourKey, client_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
}
Copy(&a->YourIp, client_ip, sizeof(IP)); Copy(&a->YourIp, client_ip, sizeof(IP));
Copy(&a->YourIp2, client_ip_2, sizeof(IP)); Copy(&a->YourIp2, client_ip_2, sizeof(IP));
@ -919,14 +1024,22 @@ bool UdpAccelInitClient(UDP_ACCEL *a, UCHAR *server_key, IP *server_ip, UINT ser
} }
IPToStr(tmp, sizeof(tmp), server_ip); IPToStr(tmp, sizeof(tmp), server_ip);
Debug("UdpAccelInitClient: server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n", tmp, server_port, server_cookie, client_cookie); Debug("UdpAccelInitClient: ver = %u, server_ip=%s, server_port=%u, server_cookie=%u, client_cookie=%u\n",
a->Version, tmp, server_port, server_cookie, client_cookie);
if (IsIP6(server_ip) != a->IsIPv6) if (IsIP6(server_ip) != a->IsIPv6)
{ {
return false; return false;
} }
Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE); if (a->Version == 2)
{
Copy(a->YourKey_V2, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V2);
}
else
{
Copy(a->YourKey, server_key, UDP_ACCELERATION_COMMON_KEY_SIZE_V1);
}
Copy(&a->YourIp, server_ip, sizeof(IP)); Copy(&a->YourIp, server_ip, sizeof(IP));
Copy(&a->YourIp2, server_ip_2, sizeof(IP)); Copy(&a->YourIp2, server_ip_2, sizeof(IP));
@ -1008,6 +1121,8 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->NoNatT = no_nat_t; a->NoNatT = no_nat_t;
a->Version = 1;
a->NatT_TranId = Rand64(); a->NatT_TranId = Rand64();
@ -1021,6 +1136,8 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->UdpSock = s; a->UdpSock = s;
Rand(a->MyKey, sizeof(a->MyKey)); Rand(a->MyKey, sizeof(a->MyKey));
Rand(a->YourKey, sizeof(a->YourKey)); Rand(a->YourKey, sizeof(a->YourKey));
Rand(a->MyKey_V2, sizeof(a->MyKey_V2));
Rand(a->YourKey_V2, sizeof(a->YourKey_V2));
Copy(&a->MyIp, ip, sizeof(IP)); Copy(&a->MyIp, ip, sizeof(IP));
a->MyPort = s->LocalPort; a->MyPort = s->LocalPort;
@ -1035,6 +1152,7 @@ UDP_ACCEL *NewUdpAccel(CEDAR *cedar, IP *ip, bool client_mode, bool random_port,
a->RecvBlockQueue = NewQueue(); a->RecvBlockQueue = NewQueue();
Rand(a->NextIv, sizeof(a->NextIv)); Rand(a->NextIv, sizeof(a->NextIv));
Rand(a->NextIv_V2, sizeof(a->NextIv_V2));
do do
{ {

@ -106,9 +106,14 @@
#define UDPACCEL_H #define UDPACCEL_H
// Constants // Constants
#define UDP_ACCELERATION_COMMON_KEY_SIZE 20 // Common key size #define UDP_ACCELERATION_COMMON_KEY_SIZE_V1 20 // V1: Common key size
#define UDP_ACCELERATION_PACKET_KEY_SIZE 20 // Key size for the packet #define UDP_ACCELERATION_PACKET_KEY_SIZE_V1 20 // V1: Key size for the packet
#define UDP_ACCELERATION_PACKET_IV_SIZE 20 // IV size for the packet #define UDP_ACCELERATION_PACKET_IV_SIZE_V1 20 // V1: IV size for the packet
#define UDP_ACCELERATION_COMMON_KEY_SIZE_V2 128 // V2: Common key size
#define UDP_ACCELERATION_PACKET_IV_SIZE_V2 12 // V2: IV size for the packet
#define UDP_ACCELERATION_PACKET_MAC_SIZE_V2 16 // V2: MAC size for the packet
#define UDP_ACCELERATION_TMP_BUF_SIZE 2048 // Temporary buffer size #define UDP_ACCELERATION_TMP_BUF_SIZE 2048 // Temporary buffer size
#define UDP_ACCELERATION_WINDOW_SIZE_MSEC (30 * 1000) // Receive window size (in milliseconds) #define UDP_ACCELERATION_WINDOW_SIZE_MSEC (30 * 1000) // Receive window size (in milliseconds)
@ -142,8 +147,8 @@ struct UDP_ACCEL
bool ClientMode; // Whether client mode bool ClientMode; // Whether client mode
bool IsInCedarPortList; // Whether included in the port list of the Cedar bool IsInCedarPortList; // Whether included in the port list of the Cedar
UINT64 Now; // Current time UINT64 Now; // Current time
UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Submit-direction common key UCHAR MyKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Submit-direction common key
UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE]; // Receiving-direction common key UCHAR YourKey[UDP_ACCELERATION_COMMON_KEY_SIZE_V1]; // Receiving-direction common key
SOCK *UdpSock; // UDP socket SOCK *UdpSock; // UDP socket
UINT MyPort; // My port number UINT MyPort; // My port number
UINT YourPort; // Port number of the other party UINT YourPort; // Port number of the other party
@ -160,7 +165,7 @@ struct UDP_ACCEL
UINT64 LastSetSrcIpAndPortTick; // Opponent's tick ??value at the time of storing the IP address and port number of the opponent at the end UINT64 LastSetSrcIpAndPortTick; // Opponent's tick ??value at the time of storing the IP address and port number of the opponent at the end
UINT64 LastRecvTick; // Tick when data has received at the end UINT64 LastRecvTick; // Tick when data has received at the end
UINT64 NextSendKeepAlive; // Next time to send a KeepAlive packet UINT64 NextSendKeepAlive; // Next time to send a KeepAlive packet
UCHAR NextIv[UDP_ACCELERATION_PACKET_IV_SIZE]; // IV to be used next UCHAR NextIv[UDP_ACCELERATION_PACKET_IV_SIZE_V1]; // IV to be used next
UINT MyCookie; // My cookie UINT MyCookie; // My cookie
UINT YourCookie; // Cookie of the other party UINT YourCookie; // Cookie of the other party
bool Inited; // Initialized flag bool Inited; // Initialized flag
@ -191,6 +196,11 @@ struct UDP_ACCEL
UCHAR UdpIpQueryPacketData[16]; // Query packet data (final transmission) UCHAR UdpIpQueryPacketData[16]; // Query packet data (final transmission)
UINT UdpIpQueryPacketSize; // Query packet data size (final transmission) UINT UdpIpQueryPacketSize; // Query packet data size (final transmission)
UCHAR UdpHostUniqueKey[SHA1_SIZE]; // Unique key for UDP self endpoint query UCHAR UdpHostUniqueKey[SHA1_SIZE]; // Unique key for UDP self endpoint query
UINT Version; // Version
UCHAR MyKey_V2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2]; // Submit-direction common key (Ver 2)
UCHAR YourKey_V2[UDP_ACCELERATION_COMMON_KEY_SIZE_V2]; // Receiving-direction common key (Ver 2)
UCHAR NextIv_V2[UDP_ACCELERATION_PACKET_IV_SIZE_V2]; // IV to be used next (Ver 2)
bool ReadRawFlagMode; // Read raw flag mode
}; };
// Function prototype // Function prototype
@ -203,7 +213,7 @@ void UdpAccelSetTick(UDP_ACCEL *a, UINT64 tick64);
BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port); BLOCK *UdpAccelProcessRecvPacket(UDP_ACCEL *a, UCHAR *buf, UINT size, IP *src_ip, UINT src_port);
void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv); void UdpAccelCalcKey(UCHAR *key, UCHAR *common_key, UCHAR *iv);
bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive); bool UdpAccelIsSendReady(UDP_ACCEL *a, bool check_keepalive);
void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, bool compressed, UINT max_size, bool high_priority); void UdpAccelSend(UDP_ACCEL *a, UCHAR *data, UINT data_size, UCHAR flag, UINT max_size, bool high_priority);
void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b); void UdpAccelSendBlock(UDP_ACCEL *a, BLOCK *b);
UINT UdpAccelCalcMss(UDP_ACCEL *a); UINT UdpAccelCalcMss(UDP_ACCEL *a);
void NatT_GetIpThread(THREAD *thread, void *param); void NatT_GetIpThread(THREAD *thread, void *param);

@ -367,8 +367,8 @@ void RouteTrackingMain(SESSION *s)
if (IPToUINT(&e->DestIP) == 0 && if (IPToUINT(&e->DestIP) == 0 &&
IPToUINT(&e->DestMask) == 0) IPToUINT(&e->DestMask) == 0)
{ {
Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n", //Debug("e->InterfaceID = %u, t->VLanInterfaceId = %u\n",
e->InterfaceID, t->VLanInterfaceId); // e->InterfaceID, t->VLanInterfaceId);
if (e->InterfaceID == t->VLanInterfaceId) if (e->InterfaceID == t->VLanInterfaceId)
{ {
@ -1148,6 +1148,12 @@ void VLanPaFree(SESSION *s)
} }
t = v->RouteState; t = v->RouteState;
if (v->TunnelCrackFw != NULL)
{
StopTunnelCrackFw(v->TunnelCrackFw);
}
// End the virtual LAN card // End the virtual LAN card
FreeVLan(v); FreeVLan(v);
@ -1156,6 +1162,7 @@ void VLanPaFree(SESSION *s)
{ {
RouteTrackingStop(s, t); RouteTrackingStop(s, t);
} }
s->PacketAdapter->Param = NULL; s->PacketAdapter->Param = NULL;
} }
@ -1250,6 +1257,18 @@ bool VLanPaInit(SESSION *s)
RouteTrackingStart(s); RouteTrackingStart(s);
} }
if (s->Cedar->Client != NULL && s->Cedar->Client->Config.EnableTunnelCrackProtect)
{
if (IsZeroIP(&s->ServerIP) == false)
{
TUNNELCRACK_FW_PARAM p = CLEAN;
InitTunnelCrackFwParamForVpn(&p, &s->ServerIP);
v->TunnelCrackFw = StartTunnelCrackFw(&p);
}
}
return true; return true;
} }

@ -151,6 +151,7 @@ struct VLAN
UINT CurrentPacketCount; // Packet number to be read next UINT CurrentPacketCount; // Packet number to be read next
void *PutBuffer; // Buffer for writing received packet void *PutBuffer; // Buffer for writing received packet
ROUTE_TRACKING *RouteState; // Routing tracking state machine ROUTE_TRACKING *RouteState; // Routing tracking state machine
TUNNELCRACK_FW *TunnelCrackFw; // TunnelCrack FW
}; };
// Instance list // Instance list

@ -1543,7 +1543,7 @@ void NnTcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT
// Create a new session because there is no existing one // Create a new session because there is no existing one
UINT public_port; UINT public_port;
if (old_tcp->Flag != TCP_SYN) if (((old_tcp->Flag & TCP_SYN) && ((old_tcp->Flag & TCP_ACK) == 0)) == false)
{ {
// If there is no existing session, pass through only for SYN packet // If there is no existing session, pass through only for SYN packet
return; return;

@ -401,8 +401,16 @@ BUF *WpcDataEntryToBuf(WPC_ENTRY *e)
} }
data_size = e->Size + 4096; data_size = e->Size + 4096;
data = Malloc(data_size); data = ZeroMalloc(data_size);
if (e->Size >= 1)
{
size = DecodeSafe64(data, e->Data, e->Size); size = DecodeSafe64(data, e->Data, e->Size);
}
else
{
size = 0;
}
b = NewBuf(); b = NewBuf();
WriteBuf(b, data, size); WriteBuf(b, data, size);

@ -1,4 +1,4 @@
BUILD_NUMBER 9680 BUILD_NUMBER 9807
VERSION 429 VERSION 444
BUILD_NAME rtm BUILD_NAME rtm
BUILD_DATE 20190228_183947 BUILD_DATE 20250416_043026

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -105,6 +105,10 @@
#ifndef ENCRYPT_H #ifndef ENCRYPT_H
#define ENCRYPT_H #define ENCRYPT_H
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#define USE_OPENSSL_AEAD_CHACHA20POLY1305
#endif
// Function of OpenSSL // Function of OpenSSL
void RAND_Init_For_SoftEther(); void RAND_Init_For_SoftEther();
void RAND_Free_For_SoftEther(); void RAND_Free_For_SoftEther();
@ -132,6 +136,17 @@ void RAND_Free_For_SoftEther();
#define AES_IV_SIZE 16 // AES IV size #define AES_IV_SIZE 16 // AES IV size
#define AES_MAX_KEY_SIZE 32 // Maximum AES key size #define AES_MAX_KEY_SIZE 32 // Maximum AES key size
// RFC 8439: ChaCha20 and Poly1305 for IETF Protocols
#define AEAD_CHACHA20_POLY1305_MAC_SIZE 16 // MAC size
#define AEAD_CHACHA20_POLY1305_NONCE_SIZE 12 // Nonce size
#define AEAD_CHACHA20_POLY1305_KEY_SIZE 32 // Key size
// OpenSSL default cipher algorithms
#define OPENSSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2"
// OpenSSL 3.0.0 to 3.0.2 has a bug with RC4-MD5. https://github.com/openssl/openssl/issues/13363 https://github.com/openssl/openssl/pull/13378
#define OPENSSL_DEFAULT_CIPHER_LIST_NO_RC4_MD5 (OPENSSL_DEFAULT_CIPHER_LIST ":!RC4-MD5")
// IANA definitions taken from IKEv1 Phase 1 // IANA definitions taken from IKEv1 Phase 1
#define SHA1_160 2 #define SHA1_160 2
#define SHA2_256 4 #define SHA2_256 4
@ -339,7 +354,7 @@ struct DH_CTX
struct CIPHER struct CIPHER
{ {
char Name[MAX_PATH]; char Name[MAX_PATH];
bool IsNullCipher; bool IsNullCipher, IsAeadCipher;
const struct evp_cipher_st *Cipher; const struct evp_cipher_st *Cipher;
struct evp_cipher_ctx_st *Ctx; struct evp_cipher_ctx_st *Ctx;
bool Encrypt; bool Encrypt;
@ -355,6 +370,24 @@ struct MD
UINT Size; UINT Size;
}; };
// Seed based rand
struct SEEDRAND
{
UCHAR InitialSeed[SHA1_SIZE];
UINT64 CurrentCounter;
};
// X.509 cert list and key
struct CERTS_AND_KEY
{
REF* Ref;
LIST* CertList;
K* Key;
UINT64 HashCache;
bool HasValidPrivateKey;
bool (*DetermineUseCallback)(char*, void*);
};
// Lock of the OpenSSL // Lock of the OpenSSL
extern LOCK **ssl_lock_obj; extern LOCK **ssl_lock_obj;
@ -379,6 +412,35 @@ UCHAR Rand8();
bool Rand1(); bool Rand1();
UINT HashPtrToUINT(void *p); UINT HashPtrToUINT(void *p);
SEEDRAND *NewSeedRand(void *seed, UINT seed_size);
void FreeSeedRand(SEEDRAND *r);
UCHAR SeedRand8(SEEDRAND *r);
void SeedRand(SEEDRAND *r, void *buf, UINT size);
USHORT SeedRand16(SEEDRAND *r);
UINT SeedRand32(SEEDRAND *r);
UINT64 SeedRand64(SEEDRAND* r);
CERTS_AND_KEY* NewCertsAndKeyFromMemory(LIST* cert_buf_list, BUF* key_buf);
CERTS_AND_KEY* NewCertsAndKeyFromObjects(LIST* cert_list, K* key, bool fast);
CERTS_AND_KEY* NewCertsAndKeyFromObjectSingle(X *cert, K* key, bool fast);
CERTS_AND_KEY* NewCertsAndKeyFromDir(wchar_t* dir_name);
bool SaveCertsAndKeyToDir(CERTS_AND_KEY *c, wchar_t* dir);
void ReleaseCertsAndKey(CERTS_AND_KEY* c);
void CleanupCertsAndKey(CERTS_AND_KEY* c);
CERTS_AND_KEY* CloneCertsAndKey(CERTS_AND_KEY* c);
void FreeCertsAndKeyList(LIST* o);
LIST* CloneCertsAndKeyList(LIST* o);
void UpdateCertsAndKeyHashCacheAndCheckedState(CERTS_AND_KEY* c);
UINT64 CalcCertsAndKeyHashCache(CERTS_AND_KEY* c);
UINT64 GetCertsAndKeyHash(CERTS_AND_KEY* c);
UINT64 GetCertsAndKeyListHash(LIST* o);
bool CheckCertsAndKey(CERTS_AND_KEY* c);
bool CertsAndKeyAlwaysUseCallback(char* sni_name, void* param);
LIST* BufToXList(BUF* b);
void FreeXList(LIST* o);
void CertTest(); void CertTest();
BIO *BufToBio(BUF *b); BIO *BufToBio(BUF *b);
BUF *BioToBuf(BIO *bio); BUF *BioToBuf(BIO *bio);
@ -438,7 +500,9 @@ bool AddX509Name(void *xn, int nid, wchar_t *str);
X509 *NewRootX509(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial); X509 *NewRootX509(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial);
X *NewRootX(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial); X *NewRootX(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial);
X509 *NewX509(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial); X509 *NewX509(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial);
X509 *NewX509Ex(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial, NAME *name_issuer);
X *NewX(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial); X *NewX(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial);
X *NewXEx(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial, NAME *name_issuer);
UINT GetDaysUntil2038(); UINT GetDaysUntil2038();
UINT GetDaysUntil2038Ex(); UINT GetDaysUntil2038Ex();
X_SERIAL *NewXSerial(void *data, UINT size); X_SERIAL *NewXSerial(void *data, UINT size);
@ -460,6 +524,8 @@ bool IsEncryptedP12(P12 *p12);
P12 *NewP12(X *x, K *k, char *password); P12 *NewP12(X *x, K *k, char *password);
X *CloneX(X *x); X *CloneX(X *x);
K *CloneK(K *k); K *CloneK(K *k);
X* CloneXFast(X* x);
K* CloneKFast(K* k);
void FreeCryptLibrary(); void FreeCryptLibrary();
void GetPrintNameFromX(wchar_t *str, UINT size, X *x); void GetPrintNameFromX(wchar_t *str, UINT size, X *x);
void GetPrintNameFromXA(char *str, UINT size, X *x); void GetPrintNameFromXA(char *str, UINT size, X *x);
@ -497,6 +563,13 @@ void RsaPublicToBin(K *k, void *data);
BUF *RsaPublicToBuf(K *k); BUF *RsaPublicToBuf(K *k);
K *RsaBinToPublic(void *data, UINT size); K *RsaBinToPublic(void *data, UINT size);
X_CRL *FileToXCrl(char *filename);
X_CRL *FileToXCrlW(wchar_t *filename);
X_CRL *BufToXCrl(BUF *b);
void FreeXCrl(X_CRL *r);
bool IsXRevokedByXCrl(X *x, X_CRL *r);
bool IsXRevoked(X *x);
DES_KEY_VALUE *DesNewKeyValue(void *value); DES_KEY_VALUE *DesNewKeyValue(void *value);
DES_KEY_VALUE *DesRandKeyValue(); DES_KEY_VALUE *DesRandKeyValue();
void DesFreeKeyValue(DES_KEY_VALUE *v); void DesFreeKeyValue(DES_KEY_VALUE *v);
@ -558,6 +631,7 @@ CIPHER *NewCipher(char *name);
void FreeCipher(CIPHER *c); void FreeCipher(CIPHER *c);
void SetCipherKey(CIPHER *c, void *key, bool enc); void SetCipherKey(CIPHER *c, void *key, bool enc);
UINT CipherProcess(CIPHER *c, void *iv, void *dest, void *src, UINT size); 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); MD *NewMd(char *name);
void FreeMd(MD *md); void FreeMd(MD *md);
@ -574,6 +648,30 @@ BUF *EasyDecrypt(BUF *src_buf);
void DisableIntelAesAccel(); void DisableIntelAesAccel();
int GetSslClientCertIndex();
void Aead_ChaCha20Poly1305_Ietf_Encrypt_Embedded(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size);
bool Aead_ChaCha20Poly1305_Ietf_Decrypt_Embedded(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size);
void Aead_ChaCha20Poly1305_Ietf_Encrypt_OpenSSL(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size);
bool Aead_ChaCha20Poly1305_Ietf_Decrypt_OpenSSL(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size);
void Aead_ChaCha20Poly1305_Ietf_Encrypt(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size);
bool Aead_ChaCha20Poly1305_Ietf_Decrypt(void *dst, void *src, UINT src_size, void *key, void *nonce, void *aad, UINT aad_size);
bool Aead_ChaCha20Poly1305_Ietf_IsOpenSSL();
void Aead_ChaCha20Poly1305_Ietf_Test();
void GetSslLibVersion(char *str, UINT size);
void GetSslLibVersion_Internal(char *str, UINT size);
bool IsSslLibVersionBuggyForRc4Md5();
bool IsSslLibVersionBuggyForRc4Md5_Internal();
#ifdef ENCRYPT_C #ifdef ENCRYPT_C
// Inner function // Inner function

@ -1292,6 +1292,12 @@ void BuildHamcore(char *dst_filename, char *src_dir, bool unix_only)
} }
} }
if (InStr(rpath, "\\node_modules\\"))
{
// Exclude node_modules in the hamcore\webroot
ok = false;
}
if (ok) if (ok)
{ {
b = ReadDump(s); b = ReadDump(s);

@ -1230,6 +1230,14 @@ bool IsEmptyUniStr(wchar_t *str)
return ret; return ret;
} }
bool UniIsFilledStr(wchar_t* str)
{
return !UniIsEmptyStr(str);
}
bool UniIsFilledUniStr(wchar_t* str)
{
return !UniIsEmptyStr(str);
}
// Check whether the specified string is a number // Check whether the specified string is a number
bool UniIsNum(wchar_t *str) bool UniIsNum(wchar_t *str)
@ -1572,6 +1580,26 @@ UINT UtfToUni(wchar_t *unistr, UINT size, char *utfstr)
return UniStrLen(unistr); return UniStrLen(unistr);
} }
void UniTrimDoubleQuotation(wchar_t *str)
{
if (str == NULL || UniStrLen(str) <= 2)
{
return;
}
if (UniStartWith(str, L"\"") && UniEndWith(str, L"\""))
{
UINT len;
UniStrCpy(str, 0, str + 1);
len = UniStrLen(str);
if (len >= 1)
{
str[len - 1] = 0;
}
}
}
// Copy the UTF-8 string to a Unicode string // Copy the UTF-8 string to a Unicode string
wchar_t *CopyUtfToUni(char *utfstr) wchar_t *CopyUtfToUni(char *utfstr)
{ {
@ -2058,6 +2086,7 @@ UINT Utf8ToUni(wchar_t *s, UINT size, BYTE *u, UINT u_size)
if (IsBigEndian()) if (IsBigEndian())
{ {
#ifndef OS_WIN32
if (sizeof(wchar_t) == 2) if (sizeof(wchar_t) == 2)
{ {
((BYTE *)&c)[0] = c1; ((BYTE *)&c)[0] = c1;
@ -2068,6 +2097,11 @@ UINT Utf8ToUni(wchar_t *s, UINT size, BYTE *u, UINT u_size)
((BYTE *)&c)[2] = c1; ((BYTE *)&c)[2] = c1;
((BYTE *)&c)[3] = c2; ((BYTE *)&c)[3] = c2;
} }
#else // OS_WIN32
// VC++ (supposed never come here)
((BYTE*)&c)[0] = c1;
((BYTE*)&c)[1] = c2;
#endif // OS_WIN32
} }
else else
{ {
@ -2586,82 +2620,172 @@ UNI_TOKEN_LIST *UnixUniParseToken(wchar_t *src, wchar_t *separator)
return ret; return ret;
} }
// Parse the token
UNI_TOKEN_LIST *UniParseToken(wchar_t *src, wchar_t *separator) // Get a standard token delimiter
wchar_t* UniDefaultTokenSplitChars()
{ {
#ifdef OS_WIN32 return L" ,\t\r\n";
UNI_TOKEN_LIST *ret; }
wchar_t *tmp;
wchar_t *str1, *str2;
UINT len, num;
#ifdef OS_UNIX
wchar_t *state = NULL;
#endif // OS_UNIX
// Check whether the specified character is in the string
bool UniIsCharInStr(wchar_t* str, wchar_t c)
{
UINT i, len;
// Validate arguments // Validate arguments
if (src == NULL) if (str == NULL)
{ {
ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST)); return false;
ret->Token = ZeroMalloc(0);
return ret;
} }
if (separator == NULL)
{
separator = L" .\t\r\n";
}
len = UniStrLen(src);
str1 = Malloc((len + 1) * sizeof(wchar_t));
str2 = Malloc((len + 1) * sizeof(wchar_t));
UniStrCpy(str1, 0, src);
UniStrCpy(str2, 0, src);
Lock(token_lock); len = UniStrLen(str);
for (i = 0;i < len;i++)
{ {
tmp = wcstok(str1, separator if (str[i] == c)
#ifdef OS_UNIX
, &state
#endif // OS_UNIX
);
num = 0;
while (tmp != NULL)
{ {
num++; return true;
tmp = wcstok(NULL, separator
#ifdef OS_UNIX
, &state
#endif // OS_UNIX
);
}
ret = Malloc(sizeof(UNI_TOKEN_LIST));
ret->NumTokens = num;
ret->Token = (wchar_t **)Malloc(sizeof(wchar_t *) * num);
num = 0;
tmp = wcstok(str2, separator
#ifdef OS_UNIX
, &state
#endif // OS_UNIX
);
while (tmp != NULL)
{
ret->Token[num] = (wchar_t *)Malloc((UniStrLen(tmp) + 1) * sizeof(wchar_t));
UniStrCpy(ret->Token[num], 0, tmp);
num++;
tmp = wcstok(NULL, separator
#ifdef OS_UNIX
, &state
#endif // OS_UNIX
);
} }
} }
Unlock(token_lock);
Free(str1); return false;
Free(str2); }
return ret;
#else // OS_WIN32 // Cut out the token from the string (not ignore the blanks between delimiters)
return UnixUniParseToken(src, separator); UNI_TOKEN_LIST* UniParseTokenWithNullStr(wchar_t* str, wchar_t* split_chars)
#endif // OS_WIN32 {
LIST* o;
UINT i, len;
BUF* b;
wchar_t zero = 0;
UNI_TOKEN_LIST* t;
// Validate arguments
if (str == NULL)
{
return UniNullToken();
}
if (split_chars == NULL)
{
split_chars = UniDefaultTokenSplitChars();
}
b = NewBuf();
o = NewListFast(NULL);
len = UniStrLen(str);
for (i = 0;i < (len + 1);i++)
{
wchar_t c = str[i];
bool flag = UniIsCharInStr(split_chars, c);
if (c == L'\0')
{
flag = true;
}
if (flag == false)
{
WriteBuf(b, &c, sizeof(wchar_t));
}
else
{
WriteBuf(b, &zero, sizeof(wchar_t));
Insert(o, UniCopyStr((wchar_t*)b->Buf));
ClearBuf(b);
}
}
t = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
t->NumTokens = LIST_NUM(o);
t->Token = ZeroMalloc(sizeof(wchar_t*) * t->NumTokens);
for (i = 0;i < t->NumTokens;i++)
{
t->Token[i] = LIST_DATA(o, i);
}
ReleaseList(o);
FreeBuf(b);
return t;
}
// Cut out the token from string (Ignore blanks between delimiters)
UNI_TOKEN_LIST* UniParseTokenWithoutNullStr(wchar_t* str, wchar_t* split_chars)
{
LIST* o;
UINT i, len;
bool last_flag;
BUF* b;
wchar_t zero = 0;
UNI_TOKEN_LIST* t;
// Validate arguments
if (str == NULL)
{
return UniNullToken();
}
if (split_chars == NULL)
{
split_chars = UniDefaultTokenSplitChars();
}
b = NewBuf();
o = NewListFast(NULL);
len = UniStrLen(str);
last_flag = false;
for (i = 0;i < (len + 1);i++)
{
wchar_t c = str[i];
bool flag = UniIsCharInStr(split_chars, c);
if (c == L'\0')
{
flag = true;
}
if (flag == false)
{
WriteBuf(b, &c, sizeof(wchar_t));
}
else
{
if (last_flag == false)
{
WriteBuf(b, &zero, sizeof(wchar_t));
if ((UniStrLen((wchar_t*)b->Buf)) != 0)
{
Insert(o, UniCopyStr((wchar_t*)b->Buf));
}
ClearBuf(b);
}
}
last_flag = flag;
}
t = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
t->NumTokens = LIST_NUM(o);
t->Token = ZeroMalloc(sizeof(wchar_t*) * t->NumTokens);
for (i = 0;i < t->NumTokens;i++)
{
t->Token[i] = LIST_DATA(o, i);
}
ReleaseList(o);
FreeBuf(b);
return t;
}
// Parse the token
UNI_TOKEN_LIST* UniParseToken(wchar_t* src, wchar_t* separator)
{
// 2020/7/20 remove strtok by dnobori
return UniParseTokenWithoutNullStr(src, separator);
} }
// Get a line from standard input // Get a line from standard input
@ -2912,13 +3036,20 @@ UINT UniToInt(wchar_t *str)
void UniToStrForSingleChars(char *dst, UINT dst_size, wchar_t *src) void UniToStrForSingleChars(char *dst, UINT dst_size, wchar_t *src)
{ {
UINT i; UINT i;
UINT size;
// Validate arguments // Validate arguments
if (dst == NULL || src == NULL) if (dst == NULL || src == NULL)
{ {
return; 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]; wchar_t s = src[i];
char d; char d;
@ -2936,6 +3067,11 @@ void UniToStrForSingleChars(char *dst, UINT dst_size, wchar_t *src)
d = ' '; d = ' ';
} }
if (i == (size - 1))
{
d = 0;
}
dst[i] = d; dst[i] = d;
} }
} }

@ -180,11 +180,13 @@ UINT StrToUtf(char *utfstr, UINT size, char *str);
UINT UtfToStr(char *str, UINT size, char *utfstr); UINT UtfToStr(char *str, UINT size, char *utfstr);
UINT UniToUtf(char *utfstr, UINT size, wchar_t *unistr); UINT UniToUtf(char *utfstr, UINT size, wchar_t *unistr);
UINT UtfToUni(wchar_t *unistr, UINT size, char *utfstr); UINT UtfToUni(wchar_t *unistr, UINT size, char *utfstr);
void UniTrimDoubleQuotation(wchar_t *str);
char *CopyUniToUtf(wchar_t *unistr); char *CopyUniToUtf(wchar_t *unistr);
char *CopyStrToUtf(char *str); char *CopyStrToUtf(char *str);
char *CopyUniToStr(wchar_t *unistr); char *CopyUniToStr(wchar_t *unistr);
wchar_t *CopyUtfToUni(char *utfstr); wchar_t *CopyUtfToUni(char *utfstr);
char *CopyUtfToStr(char *utfstr); char *CopyUtfToStr(char *utfstr);
wchar_t *CopyUtfToUni(char *utfstr);
wchar_t *UniReplaceFormatStringFor64(wchar_t *fmt); wchar_t *UniReplaceFormatStringFor64(wchar_t *fmt);
void UniToStr64(wchar_t *str, UINT64 value); void UniToStr64(wchar_t *str, UINT64 value);
UINT64 UniToInt64(wchar_t *str); UINT64 UniToInt64(wchar_t *str);
@ -198,6 +200,8 @@ UNI_TOKEN_LIST *NullUniToken();
bool UniIsNum(wchar_t *str); bool UniIsNum(wchar_t *str);
bool IsEmptyUniStr(wchar_t *str); bool IsEmptyUniStr(wchar_t *str);
bool UniIsEmptyStr(wchar_t *str); bool UniIsEmptyStr(wchar_t *str);
bool UniIsFilledStr(wchar_t* str);
bool UniIsFilledUniStr(wchar_t* str);
void InitInternational(); void InitInternational();
void FreeInternational(); void FreeInternational();
USHORT *WideToUtf16(wchar_t *str); USHORT *WideToUtf16(wchar_t *str);
@ -224,6 +228,10 @@ bool UniInStrEx(wchar_t *str, wchar_t *keyword, bool case_sensitive);
void ClearUniStr(wchar_t *str, UINT str_size); void ClearUniStr(wchar_t *str, UINT str_size);
bool UniInChar(wchar_t *string, wchar_t c); bool UniInChar(wchar_t *string, wchar_t c);
UNI_TOKEN_LIST *UniGetLines(wchar_t *str); UNI_TOKEN_LIST *UniGetLines(wchar_t *str);
wchar_t* UniDefaultTokenSplitChars();
bool UniIsCharInStr(wchar_t* str, wchar_t c);
UNI_TOKEN_LIST* UniParseTokenWithNullStr(wchar_t* str, wchar_t* split_chars);
UNI_TOKEN_LIST* UniParseTokenWithoutNullStr(wchar_t* str, wchar_t* split_chars);
#ifdef OS_UNIX #ifdef OS_UNIX
void GetCurrentCharSet(char *name, UINT size); void GetCurrentCharSet(char *name, UINT size);

Some files were not shown because too many files have changed in this diff Show More