Page MenuHomeFreeBSD

D51239.id158287.diff
No OneTemporary

D51239.id158287.diff

diff --git a/contrib/wireguard-tools/config.c b/contrib/wireguard-tools/config.c
--- a/contrib/wireguard-tools/config.c
+++ b/contrib/wireguard-tools/config.c
@@ -433,6 +433,78 @@
return false;
}
+static inline bool parse_uint16(uint16_t *device_value, const char *name, const char *value) {
+
+ if (!strlen(value)) {
+ fprintf(stderr, "Unable to parse empty string\n");
+ return false;
+ }
+
+ char *end;
+ uint32_t ret;
+ ret = strtoul(value, &end, 10);
+
+ if (*end || ret > UINT16_MAX) {
+ fprintf(stderr, "Unable to parse %s: `%s'\n", name, value);
+ exit(1);
+ }
+ *device_value = (uint16_t)ret;
+ return true;
+}
+
+static inline bool parse_uint32(uint32_t *device_value, const char *name, const char *value) {
+
+ if (!strlen(value)) {
+ fprintf(stderr, "Unable to parse empty string\n");
+ return false;
+ }
+
+ char *end;
+ uint64_t ret;
+ ret = strtoul(value, &end, 10);
+ if (*end || ret > UINT32_MAX) {
+ fprintf(stderr, "Unable to parse %s: `%s'\n", name, value);
+ exit(1);
+ }
+ *device_value = (uint32_t)ret;
+ return true;
+}
+
+static inline bool parse_bool(bool *device_value, const char *name, const char *value) {
+
+ if (!strlen(value)) {
+ fprintf(stderr, "Unable to parse empty string\n");
+ return false;
+ }
+
+ if (!strcasecmp(value, "off")) {
+ *device_value = false;
+ return true;
+ }
+
+ if (!strcasecmp(value, "on")) {
+ *device_value = true;
+ return true;
+ }
+
+ if (!char_is_digit(value[0]))
+ goto err;
+
+ char *end;
+ uint32_t ret;
+ ret = strtoul(value, &end, 10);
+
+ if (*end) {
+ fprintf(stderr, "Unable to parse %s: `%s'\n", name, value);
+ exit(1);
+ }
+ *device_value = ret != 0;
+ return true;
+err:
+ fprintf(stderr, "Boolean value is neither on/off nor 0/1: `%s'\n", value);
+ return false;
+}
+
static bool process_line(struct config_ctx *ctx, const char *line)
{
const char *value;
@@ -473,6 +545,42 @@
ret = parse_key(ctx->device->private_key, value);
if (ret)
ctx->device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
+ } else if (key_match("Jc")) {
+ ret = parse_uint16(&ctx->device->junk_packet_count, "Jc", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_JC;
+ } else if (key_match("Jmin")) {
+ ret = parse_uint16(&ctx->device->junk_packet_min_size, "Jmin", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_JMIN;
+ } else if (key_match("Jmax")) {
+ ret = parse_uint16(&ctx->device->junk_packet_max_size, "Jmax", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_JMAX;
+ } else if (key_match("S1")) {
+ ret = parse_uint16(&ctx->device->init_packet_junk_size, "S1", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_S1;
+ } else if (key_match("S2")) {
+ ret = parse_uint16(&ctx->device->response_packet_junk_size, "S2", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_S2;
+ } else if (key_match("H1")) {
+ ret = parse_uint32(&ctx->device->init_packet_magic_header, "H1", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_H1;
+ } else if (key_match("H2")) {
+ ret = parse_uint32(&ctx->device->response_packet_magic_header, "H2", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_H2;
+ } else if (key_match("H3")) {
+ ret = parse_uint32(&ctx->device->underload_packet_magic_header, "H3", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_H3;
+ } else if (key_match("H4")) {
+ ret = parse_uint32(&ctx->device->transport_packet_magic_header, "H4", value);
+ if (ret)
+ ctx->device->flags |= WGDEVICE_HAS_H4;
} else
goto error;
} else if (ctx->is_peer_section) {
@@ -490,6 +598,10 @@
ret = parse_key(ctx->last_peer->preshared_key, value);
if (ret)
ctx->last_peer->flags |= WGPEER_HAS_PRESHARED_KEY;
+ } else if (key_match("AdvancedSecurity")) {
+ ret = parse_bool(&ctx->last_peer->advanced_security, "AdvancedSecurity", value);
+ if (ret)
+ ctx->last_peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
} else
goto error;
} else
@@ -546,7 +658,7 @@
return false;
}
if (!append)
- ctx->device->flags |= WGDEVICE_REPLACE_PEERS | WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_FWMARK | WGDEVICE_HAS_LISTEN_PORT;
+ ctx->device->flags |= WGDEVICE_REPLACE_PEERS | WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_FWMARK;
return true;
}
@@ -611,6 +723,60 @@
device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
argv += 2;
argc -= 2;
+ } else if (!strcmp(argv[0], "jc") && argc >= 2 && !peer) {
+ if (!parse_uint16(&device->junk_packet_count, "jc", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_JC;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "jmin") && argc >= 2 && !peer) {
+ if (!parse_uint16(&device->junk_packet_min_size, "jmin", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_JMIN;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "jmax") && argc >= 2 && !peer) {
+ if (!parse_uint16(&device->junk_packet_max_size, "jmax", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_JMAX;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "s1") && argc >= 2 && !peer) {
+ if (!parse_uint16(&device->init_packet_junk_size, "s1", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_S1;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "s2") && argc >= 2 && !peer) {
+ if (!parse_uint16(&device->response_packet_junk_size, "s2", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_S2;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "h1") && argc >= 2 && !peer) {
+ if (!parse_uint32(&device->init_packet_magic_header, "h1", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_H1;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "h2") && argc >= 2 && !peer) {
+ if (!parse_uint32(&device->response_packet_magic_header, "h2", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_H2;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "h3") && argc >= 2 && !peer) {
+ if (!parse_uint32(&device->underload_packet_magic_header, "h3", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_H3;
+ argv += 2;
+ argc -= 2;
+ } else if (!strcmp(argv[0], "h4") && argc >= 2 && !peer) {
+ if (!parse_uint32(&device->transport_packet_magic_header, "h4", argv[1]))
+ goto error;
+ device->flags |= WGDEVICE_HAS_H4;
+ argv += 2;
+ argc -= 2;
} else if (!strcmp(argv[0], "peer") && argc >= 2) {
struct wgpeer *new_peer = calloc(1, sizeof(*new_peer));
@@ -661,6 +827,12 @@
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
argv += 2;
argc -= 2;
+ } else if (!strcmp(argv[0], "advanced-security") && argc >= 2 && peer) {
+ if (!parse_bool(&peer->advanced_security, "AdvancedSecurity", argv[1]))
+ goto error;
+ peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
+ argv += 2;
+ argc -= 2;
} else {
fprintf(stderr, "Invalid argument: %s\n", argv[0]);
goto error;
diff --git a/contrib/wireguard-tools/containers.h b/contrib/wireguard-tools/containers.h
--- a/contrib/wireguard-tools/containers.h
+++ b/contrib/wireguard-tools/containers.h
@@ -7,6 +7,7 @@
#define CONTAINERS_H
#include <stdint.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
@@ -48,7 +49,8 @@
WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
WGPEER_HAS_PUBLIC_KEY = 1U << 2,
WGPEER_HAS_PRESHARED_KEY = 1U << 3,
- WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4
+ WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4,
+ WGPEER_HAS_ADVANCED_SECURITY = 1U << 5
};
struct wgpeer {
@@ -67,6 +69,8 @@
uint64_t rx_bytes, tx_bytes;
uint16_t persistent_keepalive_interval;
+ bool advanced_security;
+
struct wgallowedip *first_allowedip, *last_allowedip;
struct wgpeer *next_peer;
};
@@ -76,7 +80,16 @@
WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
- WGDEVICE_HAS_FWMARK = 1U << 4
+ WGDEVICE_HAS_FWMARK = 1U << 4,
+ WGDEVICE_HAS_JC = 1U << 5,
+ WGDEVICE_HAS_JMIN = 1U << 6,
+ WGDEVICE_HAS_JMAX = 1U << 7,
+ WGDEVICE_HAS_S1 = 1U << 8,
+ WGDEVICE_HAS_S2 = 1U << 9,
+ WGDEVICE_HAS_H1 = 1U << 10,
+ WGDEVICE_HAS_H2 = 1U << 11,
+ WGDEVICE_HAS_H3 = 1U << 12,
+ WGDEVICE_HAS_H4 = 1U << 13
};
struct wgdevice {
@@ -92,6 +105,16 @@
uint16_t listen_port;
struct wgpeer *first_peer, *last_peer;
+
+ uint16_t junk_packet_count;
+ uint16_t junk_packet_min_size;
+ uint16_t junk_packet_max_size;
+ uint16_t init_packet_junk_size;
+ uint16_t response_packet_junk_size;
+ uint32_t init_packet_magic_header;
+ uint32_t response_packet_magic_header;
+ uint32_t underload_packet_magic_header;
+ uint32_t transport_packet_magic_header;
};
#define for_each_wgpeer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer)
diff --git a/contrib/wireguard-tools/ipc-freebsd.h b/contrib/wireguard-tools/ipc-freebsd.h
--- a/contrib/wireguard-tools/ipc-freebsd.h
+++ b/contrib/wireguard-tools/ipc-freebsd.h
@@ -91,6 +91,70 @@
dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
}
}
+ if (nvlist_exists_number(nvl_device, "jc")) {
+ number = nvlist_get_number(nvl_device, "jc");
+ if (number <= UINT16_MAX){
+ dev->junk_packet_count = number;
+ dev->flags |= WGDEVICE_HAS_JC;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "jmin")) {
+ number = nvlist_get_number(nvl_device, "jmin");
+ if (number <= UINT16_MAX){
+ dev->junk_packet_min_size = number;
+ dev->flags |= WGDEVICE_HAS_JMIN;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "jmax")) {
+ number = nvlist_get_number(nvl_device, "jmax");
+ if (number <= UINT16_MAX){
+ dev->junk_packet_max_size = number;
+ dev->flags |= WGDEVICE_HAS_JMAX;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "s1")) {
+ number = nvlist_get_number(nvl_device, "s1");
+ if (number <= UINT16_MAX){
+ dev->init_packet_junk_size = number;
+ dev->flags |= WGDEVICE_HAS_S1;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "s2")) {
+ number = nvlist_get_number(nvl_device, "s2");
+ if (number <= UINT16_MAX){
+ dev->response_packet_junk_size = number;
+ dev->flags |= WGDEVICE_HAS_S2;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h1")) {
+ number = nvlist_get_number(nvl_device, "h1");
+ if (number <= UINT32_MAX){
+ dev->init_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H1;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h2")) {
+ number = nvlist_get_number(nvl_device, "h2");
+ if (number <= UINT32_MAX){
+ dev->response_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H2;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h3")) {
+ number = nvlist_get_number(nvl_device, "h3");
+ if (number <= UINT32_MAX){
+ dev->underload_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H3;
+ }
+ }
+ if (nvlist_exists_number(nvl_device, "h4")) {
+ number = nvlist_get_number(nvl_device, "h4");
+ if (number <= UINT32_MAX){
+ dev->transport_packet_magic_header = number;
+ dev->flags |= WGDEVICE_HAS_H4;
+ }
+ }
+
if (nvlist_exists_number(nvl_device, "user-cookie")) {
number = nvlist_get_number(nvl_device, "user-cookie");
if (number <= UINT32_MAX) {
@@ -272,6 +336,24 @@
nvlist_add_binary(nvl_device, "private-key", dev->private_key, sizeof(dev->private_key));
if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
nvlist_add_number(nvl_device, "listen-port", dev->listen_port);
+ if (dev->flags & WGDEVICE_HAS_JC)
+ nvlist_add_number(nvl_device, "jc", dev->junk_packet_count);
+ if (dev->flags & WGDEVICE_HAS_JMIN)
+ nvlist_add_number(nvl_device, "jmin", dev->junk_packet_min_size);
+ if (dev->flags & WGDEVICE_HAS_JMAX)
+ nvlist_add_number(nvl_device, "jmax", dev->junk_packet_max_size);
+ if (dev->flags & WGDEVICE_HAS_S1)
+ nvlist_add_number(nvl_device, "s1", dev->init_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_S2)
+ nvlist_add_number(nvl_device, "s2", dev->response_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_H1)
+ nvlist_add_number(nvl_device, "h1", dev->init_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H2)
+ nvlist_add_number(nvl_device, "h2", dev->response_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H3)
+ nvlist_add_number(nvl_device, "h3", dev->underload_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H4)
+ nvlist_add_number(nvl_device, "h4", dev->transport_packet_magic_header);
if (dev->flags & WGDEVICE_HAS_FWMARK)
nvlist_add_number(nvl_device, "user-cookie", dev->fwmark);
if (dev->flags & WGDEVICE_REPLACE_PEERS)
diff --git a/contrib/wireguard-tools/ipc-uapi-unix.h b/contrib/wireguard-tools/ipc-uapi-unix.h
--- a/contrib/wireguard-tools/ipc-uapi-unix.h
+++ b/contrib/wireguard-tools/ipc-uapi-unix.h
@@ -14,7 +14,7 @@
#include <sys/stat.h>
#include <sys/un.h>
-#define SOCK_PATH RUNSTATEDIR "/wireguard/"
+#define SOCK_PATH RUNSTATEDIR "/amneziawg/"
#define SOCK_SUFFIX ".sock"
static FILE *userspace_interface_file(const char *iface)
diff --git a/contrib/wireguard-tools/ipc-uapi.h b/contrib/wireguard-tools/ipc-uapi.h
--- a/contrib/wireguard-tools/ipc-uapi.h
+++ b/contrib/wireguard-tools/ipc-uapi.h
@@ -51,10 +51,32 @@
fprintf(f, "fwmark=%u\n", dev->fwmark);
if (dev->flags & WGDEVICE_REPLACE_PEERS)
fprintf(f, "replace_peers=true\n");
+ if (dev->flags & WGDEVICE_HAS_JC)
+ fprintf(f, "jc=%u\n", dev->junk_packet_count);
+ if (dev->flags & WGDEVICE_HAS_JMIN)
+ fprintf(f, "jmin=%u\n", dev->junk_packet_min_size);
+ if (dev->flags & WGDEVICE_HAS_JMAX)
+ fprintf(f, "jmax=%u\n", dev->junk_packet_max_size);
+ if (dev->flags & WGDEVICE_HAS_S1)
+ fprintf(f, "s1=%u\n", dev->init_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_S2)
+ fprintf(f, "s2=%u\n", dev->response_packet_junk_size);
+ if (dev->flags & WGDEVICE_HAS_H1)
+ fprintf(f, "h1=%u\n", dev->init_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H2)
+ fprintf(f, "h2=%u\n", dev->response_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H3)
+ fprintf(f, "h3=%u\n", dev->underload_packet_magic_header);
+ if (dev->flags & WGDEVICE_HAS_H4)
+ fprintf(f, "h4=%u\n", dev->transport_packet_magic_header);
for_each_wgpeer(dev, peer) {
key_to_hex(hex, peer->public_key);
fprintf(f, "public_key=%s\n", hex);
+ if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
+ ret = -EINVAL;
+ goto out;
+ }
if (peer->flags & WGPEER_REMOVE_ME) {
fprintf(f, "remove=true\n");
continue;
@@ -183,6 +205,33 @@
} else if (!peer && !strcmp(key, "fwmark")) {
dev->fwmark = NUM(0xffffffffU);
dev->flags |= WGDEVICE_HAS_FWMARK;
+ } else if(!peer && !strcmp(key, "jc")) {
+ dev->junk_packet_count = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_JC;
+ } else if(!peer && !strcmp(key, "jmin")) {
+ dev->junk_packet_min_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_JMIN;
+ } else if(!peer && !strcmp(key, "jmax")) {
+ dev->junk_packet_max_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_JMAX;
+ } else if(!peer && !strcmp(key, "s1")) {
+ dev->init_packet_junk_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_S1;
+ } else if(!peer && !strcmp(key, "s2")) {
+ dev->response_packet_junk_size = NUM(0xffffU);
+ dev->flags |= WGDEVICE_HAS_S2;
+ } else if(!peer && !strcmp(key, "h1")) {
+ dev->init_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H1;
+ } else if(!peer && !strcmp(key, "h2")) {
+ dev->response_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H2;
+ } else if(!peer && !strcmp(key, "h3")) {
+ dev->underload_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H3;
+ } else if(!peer && !strcmp(key, "h4")) {
+ dev->transport_packet_magic_header = NUM(0xffffffffU);
+ dev->flags |= WGDEVICE_HAS_H4;
} else if (!strcmp(key, "public_key")) {
struct wgpeer *new_peer = calloc(1, sizeof(*new_peer));
diff --git a/contrib/wireguard-tools/set.c b/contrib/wireguard-tools/set.c
--- a/contrib/wireguard-tools/set.c
+++ b/contrib/wireguard-tools/set.c
@@ -18,7 +18,7 @@
int ret = 1;
if (argc < 3) {
- fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips [+|-]<ip1>/<cidr1>[,[+|-]<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
+ fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips [+|-]<ip1>/<cidr1>[,[+|-]<ip2>/<cidr2>] [advanced-security <on|off>]...] ]...\n", PROG_NAME, argv[0]);
return 1;
}
diff --git a/contrib/wireguard-tools/show.c b/contrib/wireguard-tools/show.c
--- a/contrib/wireguard-tools/show.c
+++ b/contrib/wireguard-tools/show.c
@@ -220,6 +220,24 @@
terminal_printf(" " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->listen_port);
if (device->fwmark)
terminal_printf(" " TERMINAL_BOLD "fwmark" TERMINAL_RESET ": 0x%x\n", device->fwmark);
+ if (device->junk_packet_count)
+ terminal_printf(" " TERMINAL_BOLD "jc" TERMINAL_RESET ": %u\n", device->junk_packet_count);
+ if (device->junk_packet_min_size)
+ terminal_printf(" " TERMINAL_BOLD "jmin" TERMINAL_RESET ": %u\n", device->junk_packet_min_size);
+ if (device->junk_packet_max_size)
+ terminal_printf(" " TERMINAL_BOLD "jmax" TERMINAL_RESET ": %u\n", device->junk_packet_max_size);
+ if (device->init_packet_junk_size)
+ terminal_printf(" " TERMINAL_BOLD "s1" TERMINAL_RESET ": %u\n", device->init_packet_junk_size);
+ if (device->response_packet_junk_size)
+ terminal_printf(" " TERMINAL_BOLD "s2" TERMINAL_RESET ": %u\n", device->response_packet_junk_size);
+ if (device->init_packet_magic_header)
+ terminal_printf(" " TERMINAL_BOLD "h1" TERMINAL_RESET ": %u\n", device->init_packet_magic_header);
+ if (device->response_packet_magic_header)
+ terminal_printf(" " TERMINAL_BOLD "h2" TERMINAL_RESET ": %u\n", device->response_packet_magic_header);
+ if (device->underload_packet_magic_header)
+ terminal_printf(" " TERMINAL_BOLD "h3" TERMINAL_RESET ": %u\n", device->underload_packet_magic_header);
+ if (device->transport_packet_magic_header)
+ terminal_printf(" " TERMINAL_BOLD "h4" TERMINAL_RESET ": %u\n", device->transport_packet_magic_header);
if (device->first_peer) {
sort_peers(device);
terminal_printf("\n");
@@ -260,6 +278,15 @@
printf("%s\t", maybe_key(device->private_key, device->flags & WGDEVICE_HAS_PRIVATE_KEY));
printf("%s\t", maybe_key(device->public_key, device->flags & WGDEVICE_HAS_PUBLIC_KEY));
printf("%u\t", device->listen_port);
+ printf("%u\t", device->junk_packet_count);
+ printf("%u\t", device->junk_packet_min_size);
+ printf("%u\t", device->junk_packet_max_size);
+ printf("%u\t", device->init_packet_junk_size);
+ printf("%u\t", device->response_packet_junk_size);
+ printf("%u\t", device->init_packet_magic_header);
+ printf("%u\t", device->response_packet_magic_header);
+ printf("%u\t", device->underload_packet_magic_header);
+ printf("%u\t", device->transport_packet_magic_header);
if (device->fwmark)
printf("0x%x\n", device->fwmark);
else
@@ -311,6 +338,42 @@
printf("0x%x\n", device->fwmark);
else
printf("off\n");
+ } else if(!strcmp(param, "jc")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->junk_packet_count);
+ } else if(!strcmp(param, "jmin")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->junk_packet_min_size);
+ } else if(!strcmp(param, "jmax")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->junk_packet_max_size);
+ } else if(!strcmp(param, "s1")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->init_packet_junk_size);
+ } else if(!strcmp(param, "s2")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->response_packet_junk_size);
+ } else if(!strcmp(param, "h1")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->init_packet_magic_header);
+ } else if(!strcmp(param, "h2")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->response_packet_magic_header);
+ } else if(!strcmp(param, "h3")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->underload_packet_magic_header);
+ } else if(!strcmp(param, "h4")) {
+ if (with_interface)
+ printf("%s\t", device->name);
+ printf("%u\n", device->transport_packet_magic_header);
} else if (!strcmp(param, "endpoints")) {
for_each_wgpeer(device, peer) {
if (with_interface)
diff --git a/contrib/wireguard-tools/showconf.c b/contrib/wireguard-tools/showconf.c
--- a/contrib/wireguard-tools/showconf.c
+++ b/contrib/wireguard-tools/showconf.c
@@ -46,6 +46,25 @@
key_to_base64(base64, device->private_key);
printf("PrivateKey = %s\n", base64);
}
+ if (device->flags & WGDEVICE_HAS_JC)
+ printf("Jc = %u\n", device->junk_packet_count);
+ if (device->flags & WGDEVICE_HAS_JMIN)
+ printf("Jmin = %u\n", device->junk_packet_min_size);
+ if (device->flags & WGDEVICE_HAS_JMAX)
+ printf("Jmax = %u\n", device->junk_packet_max_size);
+ if (device->flags & WGDEVICE_HAS_S1)
+ printf("S1 = %u\n", device->init_packet_junk_size);
+ if (device->flags & WGDEVICE_HAS_S2)
+ printf("S2 = %u\n", device->response_packet_junk_size);
+ if (device->flags & WGDEVICE_HAS_H1)
+ printf("H1 = %u\n", device->init_packet_magic_header);
+ if (device->flags & WGDEVICE_HAS_H2)
+ printf("H2 = %u\n", device->response_packet_magic_header);
+ if (device->flags & WGDEVICE_HAS_H3)
+ printf("H3 = %u\n", device->underload_packet_magic_header);
+ if (device->flags & WGDEVICE_HAS_H4)
+ printf("H4 = %u\n", device->transport_packet_magic_header);
+
printf("\n");
for_each_wgpeer(device, peer) {
key_to_base64(base64, peer->public_key);
@@ -54,6 +73,9 @@
key_to_base64(base64, peer->preshared_key);
printf("PresharedKey = %s\n", base64);
}
+ if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
+ printf("AdvancedSecurity = %s\n", peer->advanced_security ? "on" : "off");
+ }
if (peer->first_allowedip)
printf("AllowedIPs = ");
for_each_wgallowedip(peer, allowedip) {
diff --git a/sys/dev/wg/if_wg.c b/sys/dev/wg/if_wg.c
--- a/sys/dev/wg/if_wg.c
+++ b/sys/dev/wg/if_wg.c
@@ -70,10 +70,14 @@
#define DPRINTF(sc, ...) if (if_getflags(sc->sc_ifp) & IFF_DEBUG) if_printf(sc->sc_ifp, ##__VA_ARGS__)
/* First byte indicating packet type on the wire */
-#define WG_PKT_INITIATION htole32(1)
-#define WG_PKT_RESPONSE htole32(2)
-#define WG_PKT_COOKIE htole32(3)
-#define WG_PKT_DATA htole32(4)
+#define WG_PKT_X_DEFAULT(x, y) ((x) ? (x) : (y))
+
+#define WG_PKT_INITIATION(sc) WG_PKT_X_DEFAULT(sc->sc_socket.so_pkt_initiation, htole32(1))
+#define WG_PKT_RESPONSE(sc) WG_PKT_X_DEFAULT(sc->sc_socket.so_pkt_response, htole32(2))
+#define WG_PKT_COOKIE(sc) WG_PKT_X_DEFAULT(sc->sc_socket.so_pkt_cookie, htole32(3))
+#define WG_PKT_DATA(sc) WG_PKT_X_DEFAULT(sc->sc_socket.so_pkt_data, htole32(4))
+
+#define WG_PKT_DEFAULT_MAX htole32(4)
#define WG_PKT_PADDING 16
#define WG_KEY_SIZE 32
@@ -215,6 +219,16 @@
uint32_t so_user_cookie;
int so_fibnum;
in_port_t so_port;
+
+ uint32_t so_junk_packet_count; // Jc
+ uint32_t so_junk_packet_min_size; // Jmin
+ uint32_t so_junk_packet_max_size; // Jmax
+ uint32_t so_init_packet_junk_size; // S1
+ uint32_t so_response_packet_junk_size; // S2
+ uint32_t so_pkt_initiation; // H1
+ uint32_t so_pkt_response; // H2
+ uint32_t so_pkt_cookie; // H3
+ uint32_t so_pkt_data; // H4
};
struct wg_softc {
@@ -1288,21 +1302,78 @@
wg_send_buf(peer->p_sc, &endpoint, buf, len);
}
+static void
+wg_peer_send_buf_junk(struct wg_peer *peer, uint8_t *buf, size_t len, size_t junk_len)
+{
+ uint8_t *junk_buf;
+ size_t total_len;
+
+ if (junk_len == 0) {
+ wg_peer_send_buf(peer, buf, len);
+ return;
+ }
+
+ total_len = len + junk_len;
+ junk_buf = malloc(total_len, M_DEVBUF, M_NOWAIT);
+ if (junk_buf == NULL)
+ return;
+
+ arc4random_buf(junk_buf, junk_len);
+ memcpy(junk_buf + junk_len, buf, len);
+
+ wg_peer_send_buf(peer, junk_buf, total_len);
+
+ free(junk_buf, M_DEVBUF);
+}
+
+static void
+wg_send_junk_packets(struct wg_peer *peer)
+{
+ struct wg_softc *sc = peer->p_sc;
+ uint8_t *buf;
+ size_t size;
+ int i;
+
+ for (i = 0; i < sc->sc_socket.so_junk_packet_count; i++) {
+ /* Generate random size between min and max */
+ size = arc4random_uniform(sc->sc_socket.so_junk_packet_max_size -
+ sc->sc_socket.so_junk_packet_min_size + 1) +
+ sc->sc_socket.so_junk_packet_min_size;
+
+ buf = malloc(size, M_DEVBUF, M_NOWAIT);
+ if (buf == NULL)
+ continue;
+
+ /* Fill with random data */
+ arc4random_buf(buf, size);
+
+ /* Send to peer's endpoint */
+ wg_peer_send_buf(peer, buf, size);
+
+ free(buf, M_DEVBUF);
+ }
+}
+
static void
wg_send_initiation(struct wg_peer *peer)
{
struct wg_pkt_initiation pkt;
+ struct wg_softc *sc = peer->p_sc;
+
+ /* Send junk packets before handshake */
+ wg_send_junk_packets(peer);
if (noise_create_initiation(peer->p_remote, &pkt.s_idx, pkt.ue,
pkt.es, pkt.ets) != 0)
return;
- DPRINTF(peer->p_sc, "Sending handshake initiation to peer %" PRIu64 "\n", peer->p_id);
+ DPRINTF(sc, "Sending handshake initiation to peer %" PRIu64 "\n", peer->p_id);
- pkt.t = WG_PKT_INITIATION;
+ pkt.t = WG_PKT_INITIATION(sc);
cookie_maker_mac(&peer->p_cookie, &pkt.m, &pkt,
sizeof(pkt) - sizeof(pkt.m));
- wg_peer_send_buf(peer, (uint8_t *)&pkt, sizeof(pkt));
+ wg_peer_send_buf_junk(peer, (uint8_t *)&pkt, sizeof(pkt),
+ sc->sc_socket.so_init_packet_junk_size);
wg_timers_event_handshake_initiated(peer);
}
@@ -1318,10 +1389,11 @@
DPRINTF(peer->p_sc, "Sending handshake response to peer %" PRIu64 "\n", peer->p_id);
wg_timers_event_session_derived(peer);
- pkt.t = WG_PKT_RESPONSE;
+ pkt.t = WG_PKT_RESPONSE(peer->p_sc);
cookie_maker_mac(&peer->p_cookie, &pkt.m, &pkt,
sizeof(pkt)-sizeof(pkt.m));
- wg_peer_send_buf(peer, (uint8_t*)&pkt, sizeof(pkt));
+ wg_peer_send_buf_junk(peer, (uint8_t*)&pkt, sizeof(pkt),
+ peer->p_sc->sc_socket.so_response_packet_junk_size);
}
static void
@@ -1332,7 +1404,7 @@
DPRINTF(sc, "Sending cookie response for denied handshake message\n");
- pkt.t = WG_PKT_COOKIE;
+ pkt.t = WG_PKT_COOKIE(sc);
pkt.r_idx = idx;
cookie_checker_create_payload(&sc->sc_cookie, cm, pkt.nonce,
@@ -1389,8 +1461,8 @@
if ((pkt->p_mbuf = m = m_pullup(m, m->m_pkthdr.len)) == NULL)
goto error;
- switch (*mtod(m, uint32_t *)) {
- case WG_PKT_INITIATION:
+ uint32_t t = *mtod(m, uint32_t *);
+ if ( t == WG_PKT_INITIATION(sc)) {
init = mtod(m, struct wg_pkt_initiation *);
res = cookie_checker_validate_macs(&sc->sc_cookie, &init->m,
@@ -1423,8 +1495,7 @@
wg_peer_set_endpoint(peer, e);
wg_send_response(peer);
- break;
- case WG_PKT_RESPONSE:
+ } else if (t == WG_PKT_RESPONSE(sc)) {
resp = mtod(m, struct wg_pkt_response *);
res = cookie_checker_validate_macs(&sc->sc_cookie, &resp->m,
@@ -1457,8 +1528,7 @@
wg_peer_set_endpoint(peer, e);
wg_timers_event_session_derived(peer);
wg_timers_event_handshake_complete(peer);
- break;
- case WG_PKT_COOKIE:
+ } else if (t == WG_PKT_COOKIE(sc)) {
cook = mtod(m, struct wg_pkt_cookie *);
if ((remote = noise_remote_index(sc->sc_local, cook->r_idx)) == NULL) {
@@ -1477,7 +1547,7 @@
}
goto not_authenticated;
- default:
+ } else {
panic("invalid packet in handshake queue");
}
@@ -1595,7 +1665,7 @@
if (m == NULL)
goto out;
data = mtod(m, struct wg_pkt_data *);
- data->t = WG_PKT_DATA;
+ data->t = WG_PKT_DATA(sc);
data->r_idx = idx;
data->nonce = htole64(pkt->p_nonce);
@@ -2035,6 +2105,46 @@
return (pkt);
}
+static struct mbuf *
+wg_skip_junk_input(struct mbuf *m, struct wg_softc *sc)
+{
+ size_t assumed_offset = 0;
+ uint32_t assumed_type = 0;
+
+ if (!sc->sc_socket.so_init_packet_junk_size &&
+ !sc->sc_socket.so_response_packet_junk_size)
+ return m;
+
+ /* Check if this is an initiation packet with junk */
+ if (m->m_pkthdr.len == sizeof(struct wg_pkt_initiation) +
+ sc->sc_socket.so_init_packet_junk_size) {
+ assumed_offset = sc->sc_socket.so_init_packet_junk_size;
+ assumed_type = WG_PKT_INITIATION(sc);
+ }
+ /* Check if this is a response packet with junk */
+ else if (m->m_pkthdr.len == sizeof(struct wg_pkt_response) +
+ sc->sc_socket.so_response_packet_junk_size) {
+ assumed_offset = sc->sc_socket.so_response_packet_junk_size;
+ assumed_type = WG_PKT_RESPONSE(sc);
+ }
+
+ if (assumed_offset == 0)
+ return m;
+
+ m = m_pullup(m, assumed_offset + sizeof(uint32_t));
+ if (m == NULL)
+ return m;
+
+ /* verify packet type */
+ if (*(uint32_t *)mtodo(m, assumed_offset) != assumed_type) {
+ return m;
+ }
+
+ m_adj(m, assumed_offset);
+
+ return m;
+}
+
static bool
wg_input(struct mbuf *m, int offset, struct inpcb *inpcb,
const struct sockaddr *sa, void *_sc)
@@ -2064,6 +2174,9 @@
/* Caller provided us with `sa`, no need for this header. */
m_adj(m, offset + sizeof(struct udphdr));
+ /* Check if this packet has junk to skip, doing m_pullup if needed*/
+ m = wg_skip_junk_input(m, sc);
+
/* Pullup enough to read packet type */
if ((m = m_pullup(m, sizeof(uint32_t))) == NULL) {
if_inc_counter(sc->sc_ifp, IFCOUNTER_IQDROPS, 1);
@@ -2097,11 +2210,11 @@
}
if ((m->m_pkthdr.len == sizeof(struct wg_pkt_initiation) &&
- *mtod(m, uint32_t *) == WG_PKT_INITIATION) ||
+ *mtod(m, uint32_t *) == WG_PKT_INITIATION(sc)) ||
(m->m_pkthdr.len == sizeof(struct wg_pkt_response) &&
- *mtod(m, uint32_t *) == WG_PKT_RESPONSE) ||
+ *mtod(m, uint32_t *) == WG_PKT_RESPONSE(sc)) ||
(m->m_pkthdr.len == sizeof(struct wg_pkt_cookie) &&
- *mtod(m, uint32_t *) == WG_PKT_COOKIE)) {
+ *mtod(m, uint32_t *) == WG_PKT_COOKIE(sc))) {
if (wg_queue_enqueue_handshake(&sc->sc_handshake_queue, pkt) != 0) {
if_inc_counter(sc->sc_ifp, IFCOUNTER_IQDROPS, 1);
@@ -2109,7 +2222,7 @@
}
GROUPTASK_ENQUEUE(&sc->sc_handshake);
} else if (m->m_pkthdr.len >= sizeof(struct wg_pkt_data) +
- NOISE_AUTHTAG_LEN && *mtod(m, uint32_t *) == WG_PKT_DATA) {
+ NOISE_AUTHTAG_LEN && *mtod(m, uint32_t *) == WG_PKT_DATA(sc)) {
/* Pullup whole header to read r_idx below. */
if ((pkt->p_mbuf = m_pullup(m, sizeof(struct wg_pkt_data))) == NULL)
@@ -2600,6 +2713,8 @@
nvlist_t *nvl;
ssize_t size;
int err;
+ uint64_t s1 = 0, s2 = 0;
+ uint64_t h[5] = {0};
ifp = sc->sc_ifp;
if (wgd->wgd_size == 0 || wgd->wgd_data == NULL)
@@ -2638,6 +2753,88 @@
sc->sc_socket.so_port = new_port;
}
}
+ if (nvlist_exists_number(nvl, "jc")) {
+ uint64_t jc = nvlist_get_number(nvl, "jc");
+ if (jc > UINT8_MAX) {
+ err = EINVAL;
+ goto out_locked;
+ }
+ sc->sc_socket.so_junk_packet_count = jc;
+ }
+ if (nvlist_exists_number(nvl, "jmin")) {
+ uint64_t jmin = nvlist_get_number(nvl, "jmin");
+ if (jmin > 1200) {
+ err = EINVAL;
+ goto out_locked;
+ }
+ sc->sc_socket.so_junk_packet_min_size = jmin;
+ }
+ if (nvlist_exists_number(nvl, "jmax")) {
+ uint64_t jmax = nvlist_get_number(nvl, "jmax");
+ if (jmax > ETHERMTU || jmax < sc->sc_socket.so_junk_packet_min_size) {
+ err = EINVAL;
+ goto out_locked;
+ }
+ sc->sc_socket.so_junk_packet_max_size = jmax;
+ }
+ if (nvlist_exists_number(nvl, "s1")) {
+ s1 = nvlist_get_number(nvl, "s1");
+ if (s1 + sizeof(struct wg_pkt_initiation) > ETHERMTU) {
+ err = EINVAL;
+ goto out_locked;
+ }
+ sc->sc_socket.so_init_packet_junk_size = s1;
+ }
+ if (nvlist_exists_number(nvl, "s2")) {
+ s2 = nvlist_get_number(nvl, "s2");
+ if (s2 + sizeof(struct wg_pkt_response) > ETHERMTU) {
+ err = EINVAL;
+ goto out_locked;
+ }
+ sc->sc_socket.so_response_packet_junk_size = s2;
+ }
+ if (s1 && s2 && s1 == s2) {
+ err = EINVAL;
+ goto out_locked;
+ }
+ if (nvlist_exists_number(nvl, "h1")) {
+ h[1] = nvlist_get_number(nvl, "h1");
+ sc->sc_socket.so_pkt_initiation = h[1];
+ }
+ if (nvlist_exists_number(nvl, "h2")) {
+ h[2] = nvlist_get_number(nvl, "h2");
+ sc->sc_socket.so_pkt_response = h[2];
+ }
+ if (nvlist_exists_number(nvl, "h3")) {
+ h[3] = nvlist_get_number(nvl, "h3");
+ sc->sc_socket.so_pkt_cookie = h[3];
+ }
+ if (nvlist_exists_number(nvl, "h4")) {
+ h[4] = nvlist_get_number(nvl, "h4");
+ sc->sc_socket.so_pkt_data = h[4];
+ }
+
+ // Check magic headers
+ for(int i = 1; i <= 4; i++) {
+ if (h[i] == 0) {
+ continue;
+ }
+
+ // Magic headers should be greater than WG_PKT_DATA
+ if (h[i] <= WG_PKT_DEFAULT_MAX) {
+ err = EINVAL;
+ goto out_locked;
+ }
+
+ // Magic headers should be different
+ for(int j = i - 1; j > 0; j--) {
+ if (h[j] && h[i] == h[j]) {
+ err = EINVAL;
+ goto out_locked;
+ }
+ }
+ }
+
if (nvlist_exists_binary(nvl, "private-key")) {
const void *key = nvlist_get_binary(nvl, "private-key", &size);
if (size != WG_KEY_SIZE) {
@@ -2724,6 +2921,24 @@
if (sc->sc_socket.so_port != 0)
nvlist_add_number(nvl, "listen-port", sc->sc_socket.so_port);
+ if (sc->sc_socket.so_junk_packet_count > 0)
+ nvlist_add_number(nvl, "jc", sc->sc_socket.so_junk_packet_count);
+ if (sc->sc_socket.so_junk_packet_min_size > 0)
+ nvlist_add_number(nvl, "jmin", sc->sc_socket.so_junk_packet_min_size);
+ if (sc->sc_socket.so_junk_packet_max_size > 0)
+ nvlist_add_number(nvl, "jmax", sc->sc_socket.so_junk_packet_max_size);
+ if (sc->sc_socket.so_init_packet_junk_size > 0)
+ nvlist_add_number(nvl, "s1", sc->sc_socket.so_init_packet_junk_size);
+ if (sc->sc_socket.so_response_packet_junk_size > 0)
+ nvlist_add_number(nvl, "s2", sc->sc_socket.so_response_packet_junk_size);
+ if (sc->sc_socket.so_pkt_initiation > 0)
+ nvlist_add_number(nvl, "h1", sc->sc_socket.so_pkt_initiation);
+ if (sc->sc_socket.so_pkt_response > 0)
+ nvlist_add_number(nvl, "h2", sc->sc_socket.so_pkt_response);
+ if (sc->sc_socket.so_pkt_cookie > 0)
+ nvlist_add_number(nvl, "h3", sc->sc_socket.so_pkt_cookie);
+ if (sc->sc_socket.so_pkt_data > 0)
+ nvlist_add_number(nvl, "h4", sc->sc_socket.so_pkt_data);
if (sc->sc_socket.so_user_cookie != 0)
nvlist_add_number(nvl, "user-cookie", sc->sc_socket.so_user_cookie);
if (noise_local_keys(sc->sc_local, public_key, private_key) == 0) {
@@ -2987,6 +3202,15 @@
sc->sc_ucred = crhold(curthread->td_ucred);
sc->sc_socket.so_fibnum = curthread->td_proc->p_fibnum;
sc->sc_socket.so_port = 0;
+ sc->sc_socket.so_junk_packet_count = 0;
+ sc->sc_socket.so_junk_packet_min_size = 0;
+ sc->sc_socket.so_junk_packet_max_size = 0;
+ sc->sc_socket.so_init_packet_junk_size = 0;
+ sc->sc_socket.so_response_packet_junk_size = 0;
+ sc->sc_socket.so_pkt_initiation = 0;
+ sc->sc_socket.so_pkt_response = 0;
+ sc->sc_socket.so_pkt_cookie = 0;
+ sc->sc_socket.so_pkt_data = 0;
TAILQ_INIT(&sc->sc_peers);
sc->sc_peers_num = 0;

File Metadata

Mime Type
text/plain
Expires
Fri, Feb 6, 9:11 AM (15 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28447639
Default Alt Text
D51239.id158287.diff (34 KB)

Event Timeline