summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/config.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/config.c b/src/config.c
index 963f9e1..c420f7c 100644
--- a/src/config.c
+++ b/src/config.c
@@ -61,6 +61,16 @@ static int set_peer(struct wireguard_device *wg, void __user *user_peer, size_t
if (!peer) { /* Peer doesn't exist yet. Add a new one. */
if (in_peer.flags & WGPEER_REMOVE_ME)
return -ENODEV; /* Tried to remove a non existing peer. */
+
+ down_read(&wg->static_identity.lock);
+ if (wg->static_identity.has_identity && !memcmp(in_peer.public_key, wg->static_identity.static_public, NOISE_PUBLIC_KEY_LEN)) {
+ /* We silently ignore peers that have the same public key as the device. The reason we do it silently
+ * is that we'd like for people to be able to reuse the same set of API calls across peers. */
+ up_read(&wg->static_identity.lock);
+ goto out;
+ }
+ up_read(&wg->static_identity.lock);
+
peer = peer_rcu_get(peer_create(wg, in_peer.public_key));
if (!peer)
return -ENOMEM;
@@ -146,6 +156,16 @@ int config_set_device(struct wireguard_device *wg, void __user *user_device)
noise_set_static_identity_private_key(&wg->static_identity, NULL);
modified_static_identity = true;
} else if (memcmp(zeros, in_device.private_key, WG_KEY_LEN)) {
+ u8 public_key[NOISE_PUBLIC_KEY_LEN] = { 0 };
+ struct wireguard_peer *peer;
+ /* We remove before setting, to prevent race, which means doing two 25519-genpub ops. */
+ curve25519_generate_public(public_key, in_device.private_key);
+ peer = pubkey_hashtable_lookup(&wg->peer_hashtable, public_key);
+ if (peer) {
+ peer_put(peer);
+ peer_remove(peer);
+ }
+
noise_set_static_identity_private_key(&wg->static_identity, in_device.private_key);
modified_static_identity = true;
}