From 364a43e3dcc5a9598827a166036346be8ce08094 Mon Sep 17 00:00:00 2001 From: Paul Dee Date: Fri, 11 Aug 2023 10:34:11 +0200 Subject: [PATCH] Implement updating a client Pub+PSK when editing a client (#401) This covers the normal use-case where clients generate keys locally on their device and notify the server of their new/updated keys. The server verifies Preshared and Public keys independently of each other. Should a client generate a new tunnel which lacks a PSK and send only a Public key to the server (admin) where the earlier server created profile has a Preshared key, the server admin/user must determine the course of action: keep or remove the PSK. --- handler/routes.go | 41 +++++++++++++++++++++++++++++++++++++++++ templates/clients.html | 30 +++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/handler/routes.go b/handler/routes.go index e443af9..a2ceeaf 100644 --- a/handler/routes.go +++ b/handler/routes.go @@ -567,6 +567,45 @@ func UpdateClient(db store.IStore) echo.HandlerFunc { return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Extra Allowed IPs must be in CIDR format"}) } + // update Wireguard Client PublicKey + if client.PublicKey != _client.PublicKey && _client.PublicKey != "" { + _, err := wgtypes.ParseKey(_client.PublicKey) + if err != nil { + log.Error("Cannot verify provided Wireguard public key: ", err) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify provided Wireguard public key"}) + } + // check for duplicates + clients, err := db.GetClients(false) + if err != nil { + log.Error("Cannot get client list for duplicate public key check") + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot get client list for duplicate public key check"}) + } + for _, other := range clients { + if other.Client.PublicKey == _client.PublicKey { + log.Error("Duplicate Public Key") + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Duplicate Public Key"}) + } + } + + // When replacing any PublicKey, discard any locally stored Wireguard Client PrivateKey + // Client PubKey no longer corresponds to locally stored PrivKey. + // QR code (needs PrivateKey) for this client is no longer possible now. + + if client.PrivateKey != "" { + client.PrivateKey = "" + } + + } + + // update Wireguard Client PresharedKey + if client.PresharedKey != _client.PresharedKey && _client.PresharedKey != "" { + _, err := wgtypes.ParseKey(_client.PresharedKey) + if err != nil { + log.Error("Cannot verify provided Wireguard preshared key: ", err) + return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot verify provided Wireguard preshared key"}) + } + } + // map new data client.Name = _client.Name client.Email = _client.Email @@ -575,6 +614,8 @@ func UpdateClient(db store.IStore) echo.HandlerFunc { client.AllocatedIPs = _client.AllocatedIPs client.AllowedIPs = _client.AllowedIPs client.ExtraAllowedIPs = _client.ExtraAllowedIPs + client.PublicKey = _client.PublicKey + client.PresharedKey = _client.PresharedKey client.UpdatedAt = time.Now().UTC() // write to the database diff --git a/templates/clients.html b/templates/clients.html index 94ab634..bcd5855 100644 --- a/templates/clients.html +++ b/templates/clients.html @@ -129,6 +129,26 @@ Wireguard Clients +
+ Public and Preshared Keys + + + +
+ + +
+
+ + +
+