Skip to content

Commit

Permalink
Implement updating a client Pub+PSK when editing a client (#401)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
systemcrash authored Aug 11, 2023
1 parent 7488f28 commit 364a43e
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
41 changes: 41 additions & 0 deletions handler/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
30 changes: 29 additions & 1 deletion templates/clients.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,26 @@ <h4 class="modal-title">Edit Client</h4>
</label>
</div>
</div>
<details>
<summary><strong>Public and Preshared Keys</strong>
<i class="fas fa-info-circle" data-toggle="tooltip"
data-original-title="Update the server stored
client Public and Preshared keys.">
</i>
</summary>
<div class="form-group" style="margin-top: 1rem">
<label for="_client_public_key" class="control-label">
Public Key
</label>
<input type="text" class="form-control" id="_client_public_key" name="_client_public_key" aria-invalid="false">
</div>
<div class="form-group">
<label for="_client_preshared_key" class="control-label">
Preshared Key
</label>
<input type="text" class="form-control" id="_client_preshared_key" name="_client_preshared_key">
</div>
</details>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
Expand Down Expand Up @@ -388,6 +408,7 @@ <h4 class="modal-title">Remove</h4>


// Edit client modal event
// This fills the modal dialogue with data from the DB when we open the edit menu
$(document).ready(function () {
$("#modal_edit_client").on('show.bs.modal', function (event) {
let modal = $(this);
Expand Down Expand Up @@ -458,6 +479,9 @@ <h4 class="modal-title">Remove</h4>

modal.find("#_use_server_dns").prop("checked", client.use_server_dns);
modal.find("#_enabled").prop("checked", client.enabled);

modal.find("#_client_public_key").val(client.public_key);
modal.find("#_client_preshared_key").val(client.preshared_key);
},
error: function (jqXHR, exception) {
const responseJson = jQuery.parseJSON(jqXHR.responseText);
Expand Down Expand Up @@ -523,6 +547,8 @@ <h4 class="modal-title">Remove</h4>
}

// submitEditClient function for updating an existing client
// This sends dialogue data to the back-end when user presses "Save"
// See e.g. routes.go:UpdateClient for where data is processed/verified.
function submitEditClient() {
const client_id = $("#_client_id").val();
const name = $("#_client_name").val();
Expand All @@ -531,6 +557,8 @@ <h4 class="modal-title">Remove</h4>
const allowed_ips = $("#_client_allowed_ips").val().split(",");
let use_server_dns = false;
let extra_allowed_ips = [];
const public_key = $("#_client_public_key").val();
const preshared_key = $("#_client_preshared_key").val();

if( $("#_client_extra_allowed_ips").val() !== "" ) {
extra_allowed_ips = $("#_client_extra_allowed_ips").val().split(",");
Expand All @@ -547,7 +575,7 @@ <h4 class="modal-title">Remove</h4>
}

const data = {"id": client_id, "name": name, "email": email, "allocated_ips": allocated_ips,
"allowed_ips": allowed_ips, "extra_allowed_ips": extra_allowed_ips, "use_server_dns": use_server_dns, "enabled": enabled};
"allowed_ips": allowed_ips, "extra_allowed_ips": extra_allowed_ips, "use_server_dns": use_server_dns, "enabled": enabled, "public_key": public_key, "preshared_key": preshared_key};

$.ajax({
cache: false,
Expand Down

0 comments on commit 364a43e

Please sign in to comment.