1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2025-07-10 01:34:58 +03:00

Cedar: Implement support for WireGuard

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
	}
}
This commit is contained in:
Davide Beatrici
2020-09-01 07:00:17 +02:00
parent 8495388933
commit dd1eebdbed
22 changed files with 1611 additions and 62 deletions

View File

@ -226,8 +226,8 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
}
ipc = NewIPC(cedar, param->ClientName, param->Postfix, param->HubName,
param->UserName, param->Password, error_code, &param->ClientIp,
param->ClientPort, &param->ServerIp, param->ServerPort,
param->UserName, param->Password, param->WgKey, error_code,
&param->ClientIp, param->ClientPort, &param->ServerIp, param->ServerPort,
param->ClientHostname, param->CryptName,
param->BridgeMode, param->Mss, NULL, param->ClientCertificate, param->Layer);
@ -235,7 +235,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
}
// Start a new IPC connection
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, char *wg_key,
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
char *client_hostname, char *crypt_name,
bool bridge_mode, UINT mss, EAP_CLIENT *eap_client, X *client_certificate,
@ -337,7 +337,11 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
FreePack(p);
// Upload the authentication data
if (client_certificate != NULL)
if (IsEmptyStr(wg_key) == false)
{
p = PackLoginWithWireGuardKey(wg_key);
}
else if (client_certificate != NULL)
{
p = PackLoginWithOpenVPNCertificate(hubname, username, client_certificate);
}