Compare commits

..

14 Commits

Author SHA1 Message Date
Jason A. Donenfeld 13f4ac4cb7 ipc: linux: enforce IFNAMSIZ limit
libmnl doesn't check lengths, so do our own checking before copying the
interface name to the netlink buffer.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-08-04 16:04:36 +02:00
Jason A. Donenfeld 729242a114 man: set private key in PreUp rather than PostUp
This is probably more sensible, since there's no point in letting
traffic flow before the interface is configured.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-18 16:39:49 +02:00
Daniel Gröber e6888dd74e wg-quick: run PreUp hook after creating interface
Currently PreUp hooks run before the interface is created. This is
problematic for moving the device into a Linux VRFs as this will
currently clear all assigned IPv6 addressess (possibly a bug), so if we
did this in PostUp (i.e. before add_addr) we'll have to manually re-add
all assigned addresses. This is obviously less than ideal.

Instead create the wg device just before running PreUp hooks. We apply
this to all platforms for consistency.

Test case:

    $ ip link add vrf-test type vrf table 1234
    $ ip link add wg-test type wireguard
    $ ip addr add dev wg-test 192.168.42.42/24
    $ ip addr add dev wg-test fe80::/64

    $ ip -br addr show wg-test
    wg-test          DOWN           192.168.42.42/24 fe80::/64

    $ ip link set dev wg-test master vrf-test

    $ ip -br addr show wg-test
    wg-test          DOWN           192.168.42.42/32

Signed-off-by: Daniel Gröber <dxld@darkboxed.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-05-18 16:38:34 +02:00
Dmitry Selivanov b4f6b4f229 show: fix show all endpoints output
Currently "wg show all endpoints" prints interface name only once
while other "show all" commands print it on each line as man says.

Signed-off-by: Dmitry Selivanov <dseliv@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2023-02-08 13:47:47 -03:00
Kyle Evans 139aac59a5 ipc: freebsd: NULL out some freed memory in kernel_set_device()
The `err` path in kernel_set_device() will attempt to free() allocated
nvl_peers, but these two cases meant we could end up attempting a use
after free or a double free, as we rely on nvlist_destroy(NULL) being
a NOP as well as free(NULL).

FreeBSD-Coverity:	1500421
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-11-03 19:57:26 +01:00
Kyle Evans dbf49a7d17 ipc: freebsd: avoid leaking memory in kernel_get_device()
Primarily, front-load validation of an allowed-ip entry to before we
allocate `aip`, so that we don't need to free() it if we end up skipping
this entry.  Assert that `aip` is NULL after we exit the loop, as we
should have transfered ownership to the `peer` or freed it in all paths
through the allowed-ip loop.

FreeBSD-Coverity:	1500405
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-11-03 19:57:21 +01:00
Jason A. Donenfeld ca2e89ff21 show: apply const to right part of pointer
Without this -Wcast-qual complains:

show.c:30:43: warning: cast from 'const void *' to 'const void **' drops const qualifier [-Wcast-qual]
        const struct wgpeer *a = *(const void **)first, *b = *(const void **)second;
                                                 ^
show.c:30:71: warning: cast from 'const void *' to 'const void **' drops const qualifier [-Wcast-qual]
        const struct wgpeer *a = *(const void **)first, *b = *(const void **)second;

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-10-31 15:39:30 +01:00
Kyle Evans 7b2ae7aa2f ipc: freebsd: move if_wg path to reflect new in-tree location
When we re-added if_wg to the tree, we changed directories in dev to
strip the if_ (we don't use this prefix for other interfaces'
directories). Adjust it here as a convenience, so that when we import
wireguard-tools to FreeBSD the path will just work as-is with our usual
build.

Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-10-29 03:51:47 +02:00
Tom Yan 71799a8f6d wg-quick: linux: prevent traffic from momentarily leaking into tunnel
The wireguard route table ip rule should stay as a no-op until the
`suppress_prefixlength 0 table main` rule is in effect. Therefore, add
the wireguard default route to its route table after the latter rule is
added.

Signed-off-by: Tom Yan <tom.ty89@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-17 13:53:43 +02:00
Jason A. Donenfeld 5b9c1d6d74 global: dual license core files as MIT for FreeBSD
To make it easier for FreeBSD to import wg(8), dual license the core
files as MIT, so that they don't have any trouble.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-06-10 19:35:38 +02:00
Jason A. Donenfeld c0b68d2eaf wg-quick: android: use right regex for host-vs-IP
Looks like the "is valid ifname" regex was copy and pasted from
wg-quick.bash instead of the "is valid IP" regex.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-05-10 12:40:49 +02:00
Jason A. Donenfeld 1fd9570839 reresolve-dns: use $EPOCHSECONDS instead of $(date +%s)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2022-01-04 13:07:49 +01:00
Mikael Magnusson b906ecb614 embeddable-wg-library: add named wg_endpoint union
Define wg_endpoint as a named union to allow users of the emeddable
library to use the type in function arguments, variables etc.

Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-10-22 13:26:04 -06:00
Jason A. Donenfeld 1ee37b8e48 ipc: use more clever PnP enumerator
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-10-06 17:18:40 -06:00
34 changed files with 77 additions and 103 deletions

View File

@ -40,17 +40,19 @@ enum wg_peer_flags {
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4 WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4
}; };
typedef union wg_endpoint {
struct sockaddr addr;
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
} wg_endpoint;
typedef struct wg_peer { typedef struct wg_peer {
enum wg_peer_flags flags; enum wg_peer_flags flags;
wg_key public_key; wg_key public_key;
wg_key preshared_key; wg_key preshared_key;
union { wg_endpoint endpoint;
struct sockaddr addr;
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
} endpoint;
struct timespec64 last_handshake_time; struct timespec64 last_handshake_time;
uint64_t rx_bytes, tx_bytes; uint64_t rx_bytes, tx_bytes;

View File

@ -16,7 +16,7 @@ INTERFACE="${BASH_REMATCH[1]}"
process_peer() { process_peer() {
[[ $PEER_SECTION -ne 1 || -z $PUBLIC_KEY || -z $ENDPOINT ]] && return 0 [[ $PEER_SECTION -ne 1 || -z $PUBLIC_KEY || -z $ENDPOINT ]] && return 0
[[ $(wg show "$INTERFACE" latest-handshakes) =~ ${PUBLIC_KEY//+/\\+}\ ([0-9]+) ]] || return 0 [[ $(wg show "$INTERFACE" latest-handshakes) =~ ${PUBLIC_KEY//+/\\+}\ ([0-9]+) ]] || return 0
(( ($(date +%s) - ${BASH_REMATCH[1]}) > 135 )) || return 0 (( ($EPOCHSECONDS - ${BASH_REMATCH[1]}) > 135 )) || return 0
wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT" wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT"
reset_peer_section reset_peer_section
} }

View File

@ -62,7 +62,7 @@ ifeq ($(PLATFORM),windows)
CC := x86_64-w64-mingw32-clang CC := x86_64-w64-mingw32-clang
WINDRES := $(shell $(CC) $(CFLAGS) -print-prog-name=windres 2>/dev/null) WINDRES := $(shell $(CC) $(CFLAGS) -print-prog-name=windres 2>/dev/null)
CFLAGS += -Iwincompat/include -include wincompat/compat.h -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -flto CFLAGS += -Iwincompat/include -include wincompat/compat.h -DWINVER=0x0601 -D_WIN32_WINNT=0x0601 -flto
LDLIBS += -lws2_32 -lsetupapi -lole32 -ladvapi32 -Lwincompat LDLIBS += -lws2_32 -lsetupapi -lole32 -ladvapi32 -lntdll -Lwincompat
LDFLAGS += -flto -Wl,--dynamicbase -Wl,--nxcompat -Wl,--tsaware -mconsole LDFLAGS += -flto -Wl,--dynamicbase -Wl,--nxcompat -Wl,--tsaware -mconsole
LDFLAGS += -Wl,--major-os-version=6 -Wl,--minor-os-version=1 -Wl,--major-subsystem-version=6 -Wl,--minor-subsystem-version=1 LDFLAGS += -Wl,--major-os-version=6 -Wl,--minor-os-version=1 -Wl,--major-subsystem-version=6 -Wl,--minor-subsystem-version=1
# The use of -Wl,/delayload: here implies we're using llvm-mingw # The use of -Wl,/delayload: here implies we're using llvm-mingw

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* *

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2018-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2018-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
* *

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -4,9 +4,10 @@
* *
*/ */
#include <assert.h>
#include <sys/nv.h> #include <sys/nv.h>
#include <sys/sockio.h> #include <sys/sockio.h>
#include <dev/if_wg/if_wg.h> #include <dev/wg/if_wg.h>
#define IPC_SUPPORTS_KERNEL_INTERFACE #define IPC_SUPPORTS_KERNEL_INTERFACE
@ -118,7 +119,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname)
goto skip_peers; goto skip_peers;
for (i = 0; i < peer_count; ++i) { for (i = 0; i < peer_count; ++i) {
struct wgpeer *peer; struct wgpeer *peer;
struct wgallowedip *aip; struct wgallowedip *aip = NULL;
const nvlist_t *const *nvl_aips; const nvlist_t *const *nvl_aips;
size_t aip_count, j; size_t aip_count, j;
@ -169,11 +170,13 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname)
if (!aip_count || !nvl_aips) if (!aip_count || !nvl_aips)
goto skip_allowed_ips; goto skip_allowed_ips;
for (j = 0; j < aip_count; ++j) { for (j = 0; j < aip_count; ++j) {
if (!nvlist_exists_number(nvl_aips[j], "cidr"))
continue;
if (!nvlist_exists_binary(nvl_aips[j], "ipv4") && !nvlist_exists_binary(nvl_aips[j], "ipv6"))
continue;
aip = calloc(1, sizeof(*aip)); aip = calloc(1, sizeof(*aip));
if (!aip) if (!aip)
goto err_allowed_ips; goto err_allowed_ips;
if (!nvlist_exists_number(nvl_aips[j], "cidr"))
continue;
number = nvlist_get_number(nvl_aips[j], "cidr"); number = nvlist_get_number(nvl_aips[j], "cidr");
if (nvlist_exists_binary(nvl_aips[j], "ipv4")) { if (nvlist_exists_binary(nvl_aips[j], "ipv4")) {
binary = nvlist_get_binary(nvl_aips[j], "ipv4", &size); binary = nvlist_get_binary(nvl_aips[j], "ipv4", &size);
@ -184,7 +187,8 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname)
aip->family = AF_INET; aip->family = AF_INET;
aip->cidr = number; aip->cidr = number;
memcpy(&aip->ip4, binary, sizeof(aip->ip4)); memcpy(&aip->ip4, binary, sizeof(aip->ip4));
} else if (nvlist_exists_binary(nvl_aips[j], "ipv6")) { } else {
assert(nvlist_exists_binary(nvl_aips[j], "ipv6"));
binary = nvlist_get_binary(nvl_aips[j], "ipv6", &size); binary = nvlist_get_binary(nvl_aips[j], "ipv6", &size);
if (!binary || number > 128) { if (!binary || number > 128) {
ret = EINVAL; ret = EINVAL;
@ -193,14 +197,14 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname)
aip->family = AF_INET6; aip->family = AF_INET6;
aip->cidr = number; aip->cidr = number;
memcpy(&aip->ip6, binary, sizeof(aip->ip6)); memcpy(&aip->ip6, binary, sizeof(aip->ip6));
} else }
continue;
if (!peer->first_allowedip) if (!peer->first_allowedip)
peer->first_allowedip = aip; peer->first_allowedip = aip;
else else
peer->last_allowedip->next_allowedip = aip; peer->last_allowedip->next_allowedip = aip;
peer->last_allowedip = aip; peer->last_allowedip = aip;
aip = NULL;
continue; continue;
err_allowed_ips: err_allowed_ips:
@ -209,6 +213,9 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname)
free(aip); free(aip);
goto err_peer; goto err_peer;
} }
/* Nothing leaked, hopefully -- ownership transferred or aip freed. */
assert(aip == NULL);
skip_allowed_ips: skip_allowed_ips:
if (!dev->first_peer) if (!dev->first_peer)
dev->first_peer = peer; dev->first_peer = peer;
@ -322,6 +329,7 @@ static int kernel_set_device(struct wgdevice *dev)
nvlist_destroy(nvl_aips[j]); nvlist_destroy(nvl_aips[j]);
free(nvl_aips); free(nvl_aips);
nvlist_destroy(nvl_peers[i]); nvlist_destroy(nvl_peers[i]);
nvl_peers[i] = NULL;
goto err; goto err;
} }
if (i) { if (i) {
@ -329,9 +337,11 @@ static int kernel_set_device(struct wgdevice *dev)
for (i = 0; i < peer_count; ++i) for (i = 0; i < peer_count; ++i)
nvlist_destroy(nvl_peers[i]); nvlist_destroy(nvl_peers[i]);
free(nvl_peers); free(nvl_peers);
nvl_peers = NULL;
} }
wgd.wgd_data = nvlist_pack(nvl_device, &wgd.wgd_size); wgd.wgd_data = nvlist_pack(nvl_device, &wgd.wgd_size);
nvlist_destroy(nvl_device); nvlist_destroy(nvl_device);
nvl_device = NULL;
if (!wgd.wgd_data) if (!wgd.wgd_data)
goto err; goto err;
s = get_dgram_socket(); s = get_dgram_socket();

View File

@ -479,6 +479,12 @@ static int kernel_get_device(struct wgdevice **device, const char *iface)
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct mnlg_socket *nlg; struct mnlg_socket *nlg;
/* libmnl doesn't check the buffer size, so enforce that before using. */
if (strlen(iface) >= IFNAMSIZ) {
errno = ENAMETOOLONG;
return -ENAMETOOLONG;
}
try_again: try_again:
ret = 0; ret = 0;
*device = calloc(1, sizeof(**device)); *device = calloc(1, sizeof(**device));

View File

@ -19,10 +19,11 @@
static bool have_cached_kernel_interfaces; static bool have_cached_kernel_interfaces;
static struct hashtable cached_kernel_interfaces; static struct hashtable cached_kernel_interfaces;
static const DEVPROPKEY devpkey_name = DEVPKEY_WG_NAME; static const DEVPROPKEY devpkey_name = DEVPKEY_WG_NAME;
extern bool is_win7;
static int kernel_get_wireguard_interfaces(struct string_list *list) static int kernel_get_wireguard_interfaces(struct string_list *list)
{ {
HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); HDEVINFO dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL);
bool will_have_cached_kernel_interfaces = true; bool will_have_cached_kernel_interfaces = true;
if (dev_info == INVALID_HANDLE_VALUE) { if (dev_info == INVALID_HANDLE_VALUE) {
@ -31,9 +32,8 @@ static int kernel_get_wireguard_interfaces(struct string_list *list)
} }
for (DWORD i = 0;; ++i) { for (DWORD i = 0;; ++i) {
bool found = false; DWORD buf_len;
DWORD buf_len = 0, value_type; WCHAR adapter_name[MAX_ADAPTER_NAME];
WCHAR *buf = NULL, adapter_name[MAX_ADAPTER_NAME];
SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) }; SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) };
DEVPROPTYPE prop_type; DEVPROPTYPE prop_type;
ULONG status, problem_code; ULONG status, problem_code;
@ -46,31 +46,6 @@ static int kernel_get_wireguard_interfaces(struct string_list *list)
continue; continue;
} }
while (!SetupDiGetDeviceRegistryPropertyW(dev_info, &dev_info_data, SPDRP_HARDWAREID, &value_type, (BYTE *)buf, buf_len, &buf_len)) {
free(buf);
buf = NULL;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break;
buf = malloc(buf_len);
if (!buf)
break;
}
if (!buf || value_type != REG_MULTI_SZ || buf_len < sizeof(*buf) * 2 || buf[buf_len / sizeof(*buf) - 1] || buf[buf_len / sizeof(*buf) - 2]) {
free(buf);
continue;
}
for (WCHAR *item = buf; *item; item += wcslen(item) + 1) {
if (!_wcsicmp(item, L"wireguard")) {
found = true;
break;
}
}
free(buf);
if (!found)
continue;
if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name, if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name,
&prop_type, (PBYTE)adapter_name, &prop_type, (PBYTE)adapter_name,
sizeof(adapter_name), NULL, 0) || sizeof(adapter_name), NULL, 0) ||
@ -155,14 +130,14 @@ err_hash:
} }
} }
dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL); dev_info = SetupDiGetClassDevsExW(&GUID_DEVCLASS_NET, is_win7 ? L"ROOT\\WIREGUARD" : L"SWD\\WireGuard", NULL, DIGCF_PRESENT, NULL, NULL, NULL);
if (dev_info == INVALID_HANDLE_VALUE) if (dev_info == INVALID_HANDLE_VALUE)
return NULL; return NULL;
for (DWORD i = 0; !interfaces; ++i) { for (DWORD i = 0; !interfaces; ++i) {
bool found = false; bool found;
DWORD buf_len = 0, value_type; DWORD buf_len;
WCHAR *buf = NULL, adapter_name[MAX_ADAPTER_NAME]; WCHAR *buf, adapter_name[MAX_ADAPTER_NAME];
SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) }; SP_DEVINFO_DATA dev_info_data = { .cbSize = sizeof(SP_DEVINFO_DATA) };
DEVPROPTYPE prop_type; DEVPROPTYPE prop_type;
char *interface_name; char *interface_name;
@ -173,31 +148,6 @@ err_hash:
continue; continue;
} }
while (!SetupDiGetDeviceRegistryPropertyW(dev_info, &dev_info_data, SPDRP_HARDWAREID, &value_type, (BYTE *)buf, buf_len, &buf_len)) {
free(buf);
buf = NULL;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break;
buf = malloc(buf_len);
if (!buf)
break;
}
if (!buf || value_type != REG_MULTI_SZ || buf_len < sizeof(*buf) * 2 || buf[buf_len / sizeof(*buf) - 1] || buf[buf_len / sizeof(*buf) - 2]) {
free(buf);
continue;
}
for (WCHAR *item = buf; *item; item += wcslen(item) + 1) {
if (!_wcsicmp(item, L"wireguard")) {
found = true;
break;
}
}
free(buf);
if (!found)
continue;
if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name, if (!SetupDiGetDevicePropertyW(dev_info, &dev_info_data, &devpkey_name,
&prop_type, (PBYTE)adapter_name, &prop_type, (PBYTE)adapter_name,
sizeof(adapter_name), NULL, 0) || sizeof(adapter_name), NULL, 0) ||

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -168,7 +168,7 @@ sockets, which bypass Netfilter.) When IPv6 is in use, additional similar lines
Or, perhaps it is desirable to store private keys in encrypted form, such as through use of Or, perhaps it is desirable to store private keys in encrypted form, such as through use of
.BR pass (1): .BR pass (1):
\fBPostUp = wg set %i private-key <(pass WireGuard/private-keys/%i)\fP \fBPreUp = wg set %i private-key <(pass WireGuard/private-keys/%i)\fP
.br .br
For use on a server, the following is a more complicated example involving multiple peers: For use on a server, the following is a more complicated example involving multiple peers:

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */
@ -27,7 +27,7 @@
static int peer_cmp(const void *first, const void *second) static int peer_cmp(const void *first, const void *second)
{ {
time_t diff; time_t diff;
const struct wgpeer *a = *(const void **)first, *b = *(const void **)second; const struct wgpeer *a = *(void *const *)first, *b = *(void *const *)second;
if (!a->last_handshake_time.tv_sec && !a->last_handshake_time.tv_nsec && (b->last_handshake_time.tv_sec || b->last_handshake_time.tv_nsec)) if (!a->last_handshake_time.tv_sec && !a->last_handshake_time.tv_nsec && (b->last_handshake_time.tv_sec || b->last_handshake_time.tv_nsec))
return 1; return 1;
@ -312,9 +312,9 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
else else
printf("off\n"); printf("off\n");
} else if (!strcmp(param, "endpoints")) { } else if (!strcmp(param, "endpoints")) {
for_each_wgpeer(device, peer) {
if (with_interface) if (with_interface)
printf("%s\t", device->name); printf("%s\t", device->name);
for_each_wgpeer(device, peer) {
printf("%s\t", key(peer->public_key)); printf("%s\t", key(peer->public_key));
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6) if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
printf("%s\n", endpoint(&peer->endpoint.addr)); printf("%s\n", endpoint(&peer->endpoint.addr));

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 OR MIT */
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -855,7 +855,7 @@ static void set_dnses(unsigned int netid, const char *dnses)
if (!len) if (!len)
return; return;
xregcomp(&regex_ipnothost, "^[a-zA-Z0-9_=+.-]{1,15}$", REG_EXTENDED | REG_NOSUB); xregcomp(&regex_ipnothost, "(^[0-9.]+$)|(^.*:.*$)", REG_EXTENDED | REG_NOSUB);
for (char *dns = strtok(mutable, ", \t\n"); dns; dns = strtok(NULL, ", \t\n")) { for (char *dns = strtok(mutable, ", \t\n"); dns; dns = strtok(NULL, ", \t\n")) {
if (strchr(dns, '\'') || strchr(dns, '\\')) if (strchr(dns, '\'') || strchr(dns, '\\'))
continue; continue;

View File

@ -452,8 +452,8 @@ cmd_up() {
local i local i
get_real_interface && die "\`$INTERFACE' already exists as \`$REAL_INTERFACE'" get_real_interface && die "\`$INTERFACE' already exists as \`$REAL_INTERFACE'"
trap 'del_if; del_routes; exit' INT TERM EXIT trap 'del_if; del_routes; exit' INT TERM EXIT
execute_hooks "${PRE_UP[@]}"
add_if add_if
execute_hooks "${PRE_UP[@]}"
set_config set_config
for i in "${ADDRESSES[@]}"; do for i in "${ADDRESSES[@]}"; do
add_addr "$i" add_addr "$i"

View File

@ -420,8 +420,8 @@ cmd_up() {
local i local i
[[ -z $(ifconfig "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists" [[ -z $(ifconfig "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists"
trap 'del_if; del_routes; clean_temp; exit' INT TERM EXIT trap 'del_if; del_routes; clean_temp; exit' INT TERM EXIT
execute_hooks "${PRE_UP[@]}"
add_if add_if
execute_hooks "${PRE_UP[@]}"
set_config set_config
for i in "${ADDRESSES[@]}"; do for i in "${ADDRESSES[@]}"; do
add_addr "$i" add_addr "$i"

View File

@ -220,9 +220,9 @@ add_default() {
fi fi
local proto=-4 iptables=iptables pf=ip local proto=-4 iptables=iptables pf=ip
[[ $1 == *:* ]] && proto=-6 iptables=ip6tables pf=ip6 [[ $1 == *:* ]] && proto=-6 iptables=ip6tables pf=ip6
cmd ip $proto route add "$1" dev "$INTERFACE" table $table
cmd ip $proto rule add not fwmark $table table $table cmd ip $proto rule add not fwmark $table table $table
cmd ip $proto rule add table main suppress_prefixlength 0 cmd ip $proto rule add table main suppress_prefixlength 0
cmd ip $proto route add "$1" dev "$INTERFACE" table $table
local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd local marker="-m comment --comment \"wg-quick(8) rule for $INTERFACE\"" restore=$'*raw\n' nftable="wg-quick-$INTERFACE" nftcmd
printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "$pf" "$nftable" printf -v nftcmd '%sadd table %s %s\n' "$nftcmd" "$pf" "$nftable"
@ -327,8 +327,8 @@ cmd_up() {
local i local i
[[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists" [[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists"
trap 'del_if; exit' INT TERM EXIT trap 'del_if; exit' INT TERM EXIT
execute_hooks "${PRE_UP[@]}"
add_if add_if
execute_hooks "${PRE_UP[@]}"
set_config set_config
for i in "${ADDRESSES[@]}"; do for i in "${ADDRESSES[@]}"; do
add_addr "$i" add_addr "$i"

View File

@ -417,8 +417,8 @@ cmd_up() {
local i local i
get_real_interface && die "\`$INTERFACE' already exists as \`$REAL_INTERFACE'" get_real_interface && die "\`$INTERFACE' already exists as \`$REAL_INTERFACE'"
trap 'del_if; del_routes; exit' INT TERM EXIT trap 'del_if; del_routes; exit' INT TERM EXIT
execute_hooks "${PRE_UP[@]}"
add_if add_if
execute_hooks "${PRE_UP[@]}"
set_config set_config
for i in "${ADDRESSES[@]}"; do for i in "${ADDRESSES[@]}"; do
add_addr "$i" add_addr "$i"

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0 OR MIT
/* /*
* Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. * Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
*/ */

View File

@ -10,16 +10,22 @@
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4 #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x4
#endif #endif
extern void NTAPI RtlGetNtVersionNumbers(DWORD *major, DWORD *minor, DWORD *build);
bool is_win7 = false;
__attribute__((constructor)) static void init(void) __attribute__((constructor)) static void init(void)
{ {
char *colormode; char *colormode;
DWORD console_mode; DWORD console_mode, major, minor;
HANDLE stdout_handle; HANDLE stdout_handle;
WSADATA wsaData; WSADATA wsaData;
if (!SetDllDirectoryA("") || !SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32)) if (!SetDllDirectoryA("") || !SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32))
abort(); abort();
RtlGetNtVersionNumbers(&major, &minor, NULL);
is_win7 = (major == 6 && minor <= 1) || major < 6;
WSAStartup(MAKEWORD(2, 2), &wsaData); WSAStartup(MAKEWORD(2, 2), &wsaData);
stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // We don't close this. stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // We don't close this.