From: Lonnie Abelbeck <lists@lonnie.abelbeck.com>
To: WireGuard mailing list <wireguard@lists.zx2c4.com>
Subject: [patch] wg: add support for peer names using a file in userspace
Date: Thu, 7 Dec 2017 09:31:54 -0600 [thread overview]
Message-ID: <4B7E0154-039F-4008-9C47-C825E1474731@lonnie.abelbeck.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 437 bytes --]
Enclosed is a patch: wg: add support for peer names using a file in userspace
Disabled by default, build with WITH_PEERDATA=yes to enable peer name support.
Config [Peer] sections can optionally be [Peer-custom_name] with "show" and "showconf"
displaying the "peer-custom_name" label. Spaces are ignored.
The data file location is PEERDATAFILE, which defaults to /var/run/wg.peerdata
Comments are appreciated.
Lonnie
[-- Attachment #2: 0001-wg-add-support-for-peer-names.patch --]
[-- Type: application/octet-stream, Size: 9240 bytes --]
From 02eb8daf8c158700a94cec894434dce629962483 Mon Sep 17 00:00:00 2001
From: Lonnie Abelbeck <lonnie@abelbeck.com>
Date: Thu, 7 Dec 2017 09:07:34 -0600
Subject: [PATCH 1/1] wg: add support for peer names using a file in userspace
Disabled by default, build with WITH_PEERDATA=yes to enable peer name support.
Config [Peer] sections can optionally be [Peer-custom_name] with show and showconf
displaying the peer-custom_name label. Spaces are ignored.
The data file location is PEERDATAFILE, which defaults to /var/run/wg.peerdata
---
src/tools/Makefile | 5 +++
src/tools/config.c | 33 +++++++++++++++-
src/tools/peerdata.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/tools/peerdata.h | 20 ++++++++++
src/tools/show.c | 7 ++++
src/tools/showconf.c | 6 +++
6 files changed, 173 insertions(+), 2 deletions(-)
create mode 100644 src/tools/peerdata.c
create mode 100644 src/tools/peerdata.h
diff --git a/src/tools/Makefile b/src/tools/Makefile
index e277b2f..761ee2a 100644
--- a/src/tools/Makefile
+++ b/src/tools/Makefile
@@ -12,9 +12,11 @@ MANDIR ?= $(PREFIX)/share/man
BASHCOMPDIR ?= $(PREFIX)/share/bash-completion/completions
SYSTEMDUNITDIR ?= $(shell $(PKG_CONFIG) --variable=systemdsystemunitdir systemd 2>/dev/null || echo "$(PREFIX)/lib/systemd/system")
RUNSTATEDIR ?= /var/run
+PEERDATAFILE ?= /var/run/wg.peerdata
WITH_BASHCOMPLETION ?=
WITH_WGQUICK ?=
WITH_SYSTEMDUNITS ?=
+WITH_PEERDATA ?=
ifeq ($(WITH_BASHCOMPLETION),)
ifneq ($(strip $(wildcard $(BASHCOMPDIR))),)
@@ -40,6 +42,9 @@ CFLAGS += -std=gnu11 -D_GNU_SOURCE
CFLAGS += -Wall -Wextra
CFLAGS += -MMD -MP
CFLAGS += -DRUNSTATEDIR="\"$(RUNSTATEDIR)\""
+ifeq ($(WITH_PEERDATA),yes)
+CFLAGS += -DPEERDATA -DPEERDATAFILE="\"$(PEERDATAFILE)\""
+endif
ifeq ($(DEBUG_TOOLS),y)
CFLAGS += -g
endif
diff --git a/src/tools/config.c b/src/tools/config.c
index 1fddb64..6077a6b 100644
--- a/src/tools/config.c
+++ b/src/tools/config.c
@@ -19,6 +19,7 @@
#include "containers.h"
#include "ipc.h"
#include "encoding.h"
+#include "peerdata.h"
#define COMMENT_CHAR '#'
@@ -358,7 +359,13 @@ static bool process_line(struct config_ctx *ctx, const char *line)
ctx->is_device_section = true;
return true;
}
+#ifdef PEERDATA
+ static char peer_name[WG_PEERDATA_MAXLEN];
+ bool is_peername = !strncasecmp(line, "[Peer-", 6) && line[strlen(line) - 1] == ']';
+ if (!strcasecmp(line, "[Peer]") || is_peername) {
+#else
if (!strcasecmp(line, "[Peer]")) {
+#endif
struct wgpeer *new_peer = calloc(1, sizeof(struct wgpeer));
if (!new_peer) {
@@ -374,6 +381,15 @@ static bool process_line(struct config_ctx *ctx, const char *line)
ctx->is_peer_section = true;
ctx->is_device_section = false;
ctx->last_peer->flags |= WGPEER_REPLACE_ALLOWEDIPS;
+#ifdef PEERDATA
+ if (is_peername) {
+ strncpy(peer_name, line + 6, WG_PEERDATA_MAXLEN); /* jump over "[Peer-" */
+ peer_name[WG_PEERDATA_MAXLEN - 1] = '\0';
+ peer_name[strlen(peer_name) - 1] = '\0'; /* overwrite last character ']' */
+ } else {
+ peer_name[0] = '\0';
+ }
+#endif
return true;
}
@@ -395,8 +411,17 @@ static bool process_line(struct config_ctx *ctx, const char *line)
ret = parse_endpoint(&ctx->last_peer->endpoint.addr, value);
else if (key_match("PublicKey")) {
ret = parse_key(ctx->last_peer->public_key, value);
- if (ret)
+ if (ret) {
ctx->last_peer->flags |= WGPEER_HAS_PUBLIC_KEY;
+#ifdef PEERDATA
+ if (peer_name[0]) {
+ static char base64[WG_KEY_LEN_BASE64];
+ key_to_base64(base64, ctx->last_peer->public_key);
+ file_put_peerdata(base64, "name", peer_name);
+ peer_name[0] = '\0';
+ }
+#endif
+ }
} else if (key_match("AllowedIPs"))
ret = parse_allowedips(ctx->last_peer, &ctx->last_allowedip, value);
else if (key_match("PersistentKeepalive"))
@@ -455,8 +480,12 @@ bool config_read_init(struct config_ctx *ctx, bool append)
perror("calloc");
return false;
}
- if (!append)
+ if (!append) {
ctx->device->flags |= WGDEVICE_REPLACE_PEERS | WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_FWMARK | WGDEVICE_HAS_LISTEN_PORT;
+#ifdef PEERDATA
+ file_init_peerdata();
+#endif
+ }
return true;
}
diff --git a/src/tools/peerdata.c b/src/tools/peerdata.c
new file mode 100644
index 0000000..9bd7871
--- /dev/null
+++ b/src/tools/peerdata.c
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+#ifdef PEERDATA
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "peerdata.h"
+
+bool file_init_peerdata(void)
+{
+ FILE *f;
+ bool ret = true;
+
+ f = fopen(WG_PEERDATA_FILE, "r");
+ if (f) {
+ fclose(f);
+ if (remove(WG_PEERDATA_FILE)) {
+ perror("remove");
+ ret = false;
+ }
+ }
+ return ret;
+}
+
+bool file_put_peerdata(const char *pubkey, const char *type, const char *data)
+{
+ FILE *f;
+ char *buffer;
+ size_t buffer_len = strlen(pubkey) + strlen(type) + strlen(data) + 4;
+ bool ret = false;
+
+ f = fopen(WG_PEERDATA_FILE, "a");
+ if (!f) {
+ perror("fopen");
+ return false;
+ }
+
+ buffer = calloc(buffer_len, sizeof(char));
+ if (!buffer) {
+ perror("calloc");
+ fclose(f);
+ return false;
+ }
+
+ snprintf(buffer, buffer_len, "%s,%s,%s\n", pubkey, type, data);
+ if (fwrite(buffer, strlen(buffer), 1, f) != 1) {
+ if (errno) {
+ perror("fwrite");
+ }
+ goto out;
+ }
+ ret = true;
+
+out:
+ fclose(f);
+ free(buffer);
+ return ret;
+}
+
+char *file_get_peerdata(const char *pubkey, const char *type)
+{
+ static char data[WG_PEERDATA_MAXLEN];
+ char *data_rtn = NULL;
+ FILE *f;
+ char *buffer = NULL;
+ size_t buffer_len = 0;
+ char *line, *token;
+
+ f = fopen(WG_PEERDATA_FILE, "r");
+ if (!f) {
+ return NULL;
+ }
+
+ while (getline(&buffer, &buffer_len, f) >= 0) {
+ line = buffer;
+ if ((token = strsep(&line, ","))) {
+ if (!strcmp(token, pubkey)) {
+ if ((token = strsep(&line, ","))) {
+ if (!strcmp(token, type)) {
+ if ((token = strsep(&line, "\n"))) {
+ strncpy(data, token, WG_PEERDATA_MAXLEN);
+ data[WG_PEERDATA_MAXLEN - 1] = '\0';
+ data_rtn = data;
+ goto out;
+ }
+ }
+ }
+ }
+ }
+ }
+
+out:
+ fclose(f);
+ free(buffer);
+ return data_rtn;
+}
+
+#endif
diff --git a/src/tools/peerdata.h b/src/tools/peerdata.h
new file mode 100644
index 0000000..42380f0
--- /dev/null
+++ b/src/tools/peerdata.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2015-2017 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ */
+
+#ifndef PEERDATA_H
+#define PEERDATA_H
+
+#ifdef PEERDATA
+#define WG_PEERDATA_FILE PEERDATAFILE
+#define WG_PEERDATA_MAXLEN 64
+
+#include <stdbool.h>
+
+bool file_init_peerdata(void);
+bool file_put_peerdata(const char *pubkey, const char *type, const char *data);
+char *file_get_peerdata(const char *pubkey, const char *type);
+#endif
+
+#endif
diff --git a/src/tools/show.c b/src/tools/show.c
index c5be788..bb37463 100644
--- a/src/tools/show.c
+++ b/src/tools/show.c
@@ -21,6 +21,7 @@
#include "terminal.h"
#include "encoding.h"
#include "subcommands.h"
+#include "peerdata.h"
static int peer_cmp(const void *first, const void *second)
{
@@ -222,7 +223,13 @@ static void pretty_print(struct wgdevice *device)
terminal_printf("\n");
}
for_each_wgpeer(device, peer) {
+#ifdef PEERDATA
+ char *pubkey = key(peer->public_key);
+ char *peerdata = file_get_peerdata(pubkey, "name");
+ terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer%s%s" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", (peerdata ? "-" : ""), (peerdata ? peerdata : ""), pubkey);
+#else
terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));
+#endif
if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
terminal_printf(" " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(peer->preshared_key));
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
diff --git a/src/tools/showconf.c b/src/tools/showconf.c
index 2e3fbd4..443bccc 100644
--- a/src/tools/showconf.c
+++ b/src/tools/showconf.c
@@ -16,6 +16,7 @@
#include "encoding.h"
#include "ipc.h"
#include "subcommands.h"
+#include "peerdata.h"
int showconf_main(int argc, char *argv[])
{
@@ -48,7 +49,12 @@ int showconf_main(int argc, char *argv[])
printf("\n");
for_each_wgpeer(device, peer) {
key_to_base64(base64, peer->public_key);
+#ifdef PEERDATA
+ char *peerdata = file_get_peerdata(base64, "name");
+ printf("[Peer%s%s]\nPublicKey = %s\n", (peerdata ? "-" : ""), (peerdata ? peerdata : ""), base64);
+#else
printf("[Peer]\nPublicKey = %s\n", base64);
+#endif
if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
key_to_base64(base64, peer->preshared_key);
printf("PresharedKey = %s\n", base64);
--
1.8.3.1
[-- Attachment #3: Type: text/plain, Size: 2 bytes --]
next reply other threads:[~2017-12-07 15:24 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-07 15:31 Lonnie Abelbeck [this message]
2017-12-08 4:23 ` Jason A. Donenfeld
2017-12-08 4:26 ` Jason A. Donenfeld
2017-12-08 13:42 ` [patch] " Lonnie Abelbeck
2017-12-08 18:45 ` Jason A. Donenfeld
2017-12-08 19:00 ` Lonnie Abelbeck
2017-12-08 20:39 ` Jason A. Donenfeld
2017-12-09 1:09 ` Eric Light
2017-12-09 11:32 ` Matthias Urlichs
2018-03-01 15:36 ` Damian Kaczkowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B7E0154-039F-4008-9C47-C825E1474731@lonnie.abelbeck.com \
--to=lists@lonnie.abelbeck.com \
--cc=wireguard@lists.zx2c4.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).