Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144137047
D51239.id158287.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
34 KB
Referenced Files
None
Subscribers
None
D51239.id158287.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D51239: Support for DPI-bypassing extension on top of WireGuard protocol
Attached
Detach File
Event Timeline
Log In to Comment