Please note that the implementation is not 100% conformant to the protocol whitepaper (https://www.wireguard.com/papers/wireguard.pdf).
More specifically: all peers are expected to send a handshake initiation once the current keypair is about to expire or is expired.
I decided not to do that because our implementation is meant to act as a server only. A true WireGuard peer acts, instead, as both a client and a server.
Once the keypair is expired, we immediately delete the session.
The cookie mechanism can be implemented in future.
As for authentication: unfortunately using the already existing methods is not possible due to the protocol not providing a way to send strings to a peer.
That's because WireGuard doesn't have a concept of "users": it identifies a peer through the public key, which is determined using the source address.
As a solution, this commit adds a special authentication method: once we receive the handshake initiation message and decrypt the peer's public key, we check whether it's in the allowed key list.
If it is, we retrieve the associated Virtual Hub and user; if the hub exists and the user is in it, the authentication is successful.
The allowed key list is stored in the configuration file like this:
declare WireGuardKeyList
{
declare 96oA7iMvjn7oXiG3ghBDPaSUytT75uXceLV+Fx3XMlM=
{
string Hub DEFAULT
string User user
}
}
WireGuard does not provide any configuration messages, meaning that we cannot push the IP address we receive from the DHCP server to the client.
In order to overcome the limitation we don't perform any DHCP operations and instead just extract the source IP address from the first IPv4 packet we receive in the tunnel.
The gateway address and the subnet mask can be set using the new "SetStaticNetwork" command. The values can be retrieved using "OptionsGet".
In future we will add a "allowed source IP addresses" function, similar to what the original WireGuard implementation provides.
================================================================================
SetStaticNetwork command - Set Virtual Hub static IPv4 network parameters
Help for command "SetStaticNetwork"
Purpose:
Set Virtual Hub static IPv4 network parameters
Description:
Set the static IPv4 network parameters for the Virtual Hub. They are used when DHCP is not available (e.g. WireGuard sessions).
You can get the current settings by using the OptionsGet command.
Usage:
SetStaticNetwork [/GATEWAY:gateway] [/SUBNET:subnet]
Parameters:
/GATEWAY - Specify the IP address of the gateway that will be used for internet communication.
/SUBNET - Specify the subnet mask, required to determine the size of the local VPN network.
The WireGuard implementation will have two options that should not have a fixed default value, because they represent two keys (one is preshared, the other is private).
Instead of handling these two options differently in ProtoNewContainer(), this commit adds a new function to PROTO_IMPL: ProtoOptionString().
ProtoOptionString() takes the option's name as argument and returns a heap-allocated string that will be used as value. The function returns NULL when the option doesn't need a randomized value.
This new implementation can be easily compiled and executed without the need for other components to be present.
It relies on standard C functions, aside from stat() which is part of POSIX but available on Windows as well.
There's only one third-party dependency, which is tinydir: a single-file header-only library for traversing directories.
2575 // Address
at_least: At condition size < 1U, the value of size must be at least 1.
cannot_single: At condition size < 1U, the value of size cannot be equal to 0.
dead_error_condition: The condition size < 1U cannot be true.
2576 if (size < 1)
2577 {
CID 287533 (#1 of 1): Logically dead code (DEADCODE)dead_error_line: Execution cannot reach this statement: goto LABEL_ERROR;.
2578 goto LABEL_ERROR;
2579 }
CID 355460 (#1 of 1): Dereference before null check (REVERSE_INULL)check_after_deref: Null-checking p suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
737 if (p == NULL)
738 {
739 return false;
740 }
CID 287561 (#1 of 1): Array compared against 0 (NO_EFFECT)array_null: Comparing an array to null is not useful: src == NULL, since the test will always evaluate as true.
Was src formerly declared as a pointer?
3748 if (cedar == NULL || src == NULL || dst == NULL)
3749 {
3750 return false;
3751 }
(gdb) bt
0 0x00007f43857a5e14 in __GI___pthread_mutex_init (mutex=0x0, mutexattr=0x0) at pthread_mutex_init.c:89
1 0x00007f4385eaaf1b in UnixNewLock () at SoftEtherVPN/src/Mayaqua/Unix.c:1845
2 0x00007f4385e92331 in NewLockMain () at SoftEtherVPN/src/Mayaqua/Object.c:89
3 0x00007f4385e92359 in NewLock () at SoftEtherVPN/src/Mayaqua/Object.c:101
4 0x00007f4385e92765 in NewCounter () at SoftEtherVPN/src/Mayaqua/Object.c:171
5 0x00007f4385e92e76 in NewRef () at SoftEtherVPN/src/Mayaqua/Object.c:339
6 0x00007f4385e76939 in NewSkEx (no_compact=0) at SoftEtherVPN/src/Mayaqua/Memory.c:863
7 0x00007f4385e68c95 in NormalizePathW (
dst=0x7ffe65932940 L"\xd6ff2ffb\xfbf14ce5\xad8669ca\x41998a9c\x5107d62d\x8d2ab3f2\x37ceaad2\xffc947ec\xad8ed8d8\x33e9f2f7\xc05723a9\x843263e3\x5516beb3\x12571e2a\xd81405f3\xf92194fe\xd807aa98\x12835b01\x243185be\x550c7dc3\xfd74170d\x12835b01\x553185be\x550c7dc3\x72be5d74\x80deb1fe\x9bdc06a7\xc19bf1f4\x72be5d74\x80deb1fe\x9bdc06a7\xc19bf174\x894d4018\xc54302b8\x145dc92\x143b3917\x62aa4fb8\x915764b1\xd5e11bef\x9d5fbc5\xb956c25b\x59f111f1\x923f82a4\xab1c5ed5\x3956c25b\x59f111f1\x923f82a4\xab1c5ed5\xbaeb40", size=2048, src=<optimized out>)
at SoftEtherVPN/src/Mayaqua/FileIO.c:1960
8 0x00007f4385e69188 in ConbinePathW (
dst=0x7ffe65932940 L"\xd6ff2ffb\xfbf14ce5\xad8669ca\x41998a9c\x5107d62d\x8d2ab3f2\x37ceaad2\xffc947ec\xad8ed8d8\x33e9f2f7\xc05723a9\x843263e3\x5516beb3\x12571e2a\xd81405f3\xf92194fe\xd807aa98\x12835b01\x243185be\x550c7dc3\xfd74170d\x12835b01\x553185be\x550c7dc3\x72be5d74\x80deb1fe\x9bdc06a7\xc19bf1f4\x72be5d74\x80deb1fe\x9bdc06a7\xc19bf174\x894d4018\xc54302b8\x145dc92\x143b3917\x62aa4fb8\x915764b1\xd5e11bef\x9d5fbc5\xb956c25b\x59f111f1\x923f82a4\xab1c5ed5\x3956c25b\x59f111f1\x923f82a4\xab1c5ed5\xbaeb40", size=2048,
dirname=0xbace10 L"/root/.local/bin", filename=0x7ffe65932100 L"SoftEtherVPN/build/vpntest") at SoftEtherVPN/src/Mayaqua/FileIO.c:1686
9 0x00007f4385e6af48 in UnixGetExeNameW (name=0x7f4385ede820 <exe_file_name_w> L"/tmp/a.out", size=2048, arg=0xbb5050 L"./vpntest") at SoftEtherVPN/src/Mayaqua/FileIO.c:1401
10 0x00007f4385e6b04b in InitGetExeName (arg=<optimized out>) at SoftEtherVPN/src/Mayaqua/FileIO.c:1367
11 0x00007f4385e7470a in InitMayaqua (memcheck=memcheck@entry=0, debug=debug@entry=1, argc=argc@entry=3, argv=argv@entry=0x7ffe659340e8)
at SoftEtherVPN/src/Mayaqua/Mayaqua.c:456
12 0x0000000000401282 in main (argc=3, argv=0x7ffe659340e8) at SoftEtherVPN/src/vpntest/vpntest.c:259
"2050 LA_DEL_CRL" - this entry appear in logfile when you delete cert from Certificate Revocation List. Thats why need to change it.
"2051 LA_SET_CRL" - this entry must appear in logfile when you edit cert in Certificate Revocation List, but it doesn't happen (perhaps it's a bug)
The script on our server bumps the build number for every new version + commit combination.
Each combination is associated to a unique build number and vice versa.
There's a separate counter for each version.
The reason why we cannot just use "git describe --tags --dirty" is because it relies on the last tag's name and generates a string like "5.01.9674-212-g54280853".
What we want, instead, is the last part of the version to be increased for every build.
Then, once we consider the branch stable enough, we create a tag like "5.01" and bump the version immediately after the new release.
Please note that for pull requests the build number will always be 0, because the secret token is only available in the Nightly pipeline.
The BUILD_NUMBER option controls the last part of the version, allowing us to increase it for each build.
This commit also adds version.py, which simply prints the version (e.g. "5.01") specified in CMakeLists.txt.
The script will be used to determine the build number.
Since 35200a29ea we build complete installers using CMake, meaning that there's no need for BuildUtil anymore.
MSBuild projects that are not migrated to CMake yet are kept for reference.
This commit also updates BUILD_WINDOWS.md so that it mentions Visual Studio 2019 instead of 2017.