wg: allow for NULL keys everywhere
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
e7923ba775
commit
e77a77a805
13
src/config.c
13
src/config.c
|
@ -318,9 +318,11 @@ static bool process_line(struct config_ctx *ctx, const char *line)
|
||||||
} else if (ctx->is_peer_section) {
|
} else if (ctx->is_peer_section) {
|
||||||
if (key_match("Endpoint"))
|
if (key_match("Endpoint"))
|
||||||
ret = parse_endpoint(&ctx->last_peer->endpoint.addr, value);
|
ret = parse_endpoint(&ctx->last_peer->endpoint.addr, value);
|
||||||
else if (key_match("PublicKey"))
|
else if (key_match("PublicKey")) {
|
||||||
ret = parse_key(ctx->last_peer->public_key, value);
|
ret = parse_key(ctx->last_peer->public_key, value);
|
||||||
else if (key_match("AllowedIPs"))
|
if (ret)
|
||||||
|
ctx->last_peer->flags |= WGPEER_HAS_PUBLIC_KEY;
|
||||||
|
} else if (key_match("AllowedIPs"))
|
||||||
ret = parse_allowedips(ctx->last_peer, &ctx->last_allowedip, value);
|
ret = parse_allowedips(ctx->last_peer, &ctx->last_allowedip, value);
|
||||||
else if (key_match("PersistentKeepalive"))
|
else if (key_match("PersistentKeepalive"))
|
||||||
ret = parse_persistent_keepalive(&ctx->last_peer->persistent_keepalive_interval, &ctx->last_peer->flags, value);
|
ret = parse_persistent_keepalive(&ctx->last_peer->persistent_keepalive_interval, &ctx->last_peer->flags, value);
|
||||||
|
@ -328,7 +330,7 @@ static bool process_line(struct config_ctx *ctx, const char *line)
|
||||||
ret = parse_key(ctx->last_peer->preshared_key, value);
|
ret = parse_key(ctx->last_peer->preshared_key, value);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
memset(ctx->last_peer->preshared_key, 0, WG_KEY_LEN);
|
memset(ctx->last_peer->preshared_key, 0, WG_KEY_LEN);
|
||||||
else
|
else if (!key_is_zero(ctx->last_peer->preshared_key))
|
||||||
ctx->last_peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
ctx->last_peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
||||||
} else
|
} else
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -390,7 +392,7 @@ struct wgdevice *config_read_finish(struct config_ctx *ctx)
|
||||||
struct wgpeer *peer;
|
struct wgpeer *peer;
|
||||||
|
|
||||||
for_each_wgpeer(ctx->device, peer) {
|
for_each_wgpeer(ctx->device, peer) {
|
||||||
if (key_is_zero(peer->public_key)) {
|
if (!(peer->flags & WGPEER_HAS_PUBLIC_KEY)) {
|
||||||
fprintf(stderr, "A peer is missing a public key\n");
|
fprintf(stderr, "A peer is missing a public key\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -548,7 +550,8 @@ struct wgdevice *config_read_cmd(char *argv[], int argc)
|
||||||
if (read_keyfile(key_line, argv[1])) {
|
if (read_keyfile(key_line, argv[1])) {
|
||||||
if (!parse_key(peer->preshared_key, key_line))
|
if (!parse_key(peer->preshared_key, key_line))
|
||||||
goto error;
|
goto error;
|
||||||
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
if (!key_is_zero(peer->preshared_key))
|
||||||
|
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
||||||
} else
|
} else
|
||||||
goto error;
|
goto error;
|
||||||
argv += 2;
|
argv += 2;
|
||||||
|
|
|
@ -26,8 +26,9 @@ struct wgallowedip {
|
||||||
enum {
|
enum {
|
||||||
WGPEER_REMOVE_ME = 1U << 0,
|
WGPEER_REMOVE_ME = 1U << 0,
|
||||||
WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
|
WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
|
||||||
WGPEER_HAS_PRESHARED_KEY = 1U << 2,
|
WGPEER_HAS_PUBLIC_KEY = 1U << 2,
|
||||||
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 3
|
WGPEER_HAS_PRESHARED_KEY = 1U << 3,
|
||||||
|
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wgpeer {
|
struct wgpeer {
|
||||||
|
@ -53,8 +54,9 @@ struct wgpeer {
|
||||||
enum {
|
enum {
|
||||||
WGDEVICE_REPLACE_PEERS = 1U << 0,
|
WGDEVICE_REPLACE_PEERS = 1U << 0,
|
||||||
WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
|
WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
|
||||||
WGDEVICE_HAS_LISTEN_PORT = 1U << 2,
|
WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
|
||||||
WGDEVICE_HAS_FWMARK = 1U << 3
|
WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
|
||||||
|
WGDEVICE_HAS_FWMARK = 1U << 4
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wgdevice {
|
struct wgdevice {
|
||||||
|
|
25
src/ipc.c
25
src/ipc.c
|
@ -328,7 +328,7 @@ static int userspace_get_device(struct wgdevice **out, const char *interface)
|
||||||
if (!key_from_hex(dev->private_key, value))
|
if (!key_from_hex(dev->private_key, value))
|
||||||
break;
|
break;
|
||||||
curve25519_generate_public(dev->public_key, dev->private_key);
|
curve25519_generate_public(dev->public_key, dev->private_key);
|
||||||
dev->flags |= WGDEVICE_HAS_PRIVATE_KEY;
|
dev->flags |= WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_PUBLIC_KEY;
|
||||||
} else if (!peer && !strcmp(key, "listen_port")) {
|
} else if (!peer && !strcmp(key, "listen_port")) {
|
||||||
dev->listen_port = NUM(0xffffU);
|
dev->listen_port = NUM(0xffffU);
|
||||||
dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
|
dev->flags |= WGDEVICE_HAS_LISTEN_PORT;
|
||||||
|
@ -350,10 +350,12 @@ static int userspace_get_device(struct wgdevice **out, const char *interface)
|
||||||
peer = new_peer;
|
peer = new_peer;
|
||||||
if (!key_from_hex(peer->public_key, value))
|
if (!key_from_hex(peer->public_key, value))
|
||||||
break;
|
break;
|
||||||
|
peer->flags |= WGPEER_HAS_PUBLIC_KEY;
|
||||||
} else if (peer && !strcmp(key, "preshared_key")) {
|
} else if (peer && !strcmp(key, "preshared_key")) {
|
||||||
if (!key_from_hex(peer->preshared_key, value))
|
if (!key_from_hex(peer->preshared_key, value))
|
||||||
break;
|
break;
|
||||||
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
if (!key_is_zero(peer->preshared_key))
|
||||||
|
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
||||||
} else if (peer && !strcmp(key, "endpoint")) {
|
} else if (peer && !strcmp(key, "endpoint")) {
|
||||||
char *begin, *end;
|
char *begin, *end;
|
||||||
struct addrinfo *resolved;
|
struct addrinfo *resolved;
|
||||||
|
@ -744,12 +746,17 @@ static int parse_peer(const struct nlattr *attr, void *data)
|
||||||
case WGPEER_A_UNSPEC:
|
case WGPEER_A_UNSPEC:
|
||||||
break;
|
break;
|
||||||
case WGPEER_A_PUBLIC_KEY:
|
case WGPEER_A_PUBLIC_KEY:
|
||||||
if (mnl_attr_get_payload_len(attr) == sizeof(peer->public_key))
|
if (mnl_attr_get_payload_len(attr) == sizeof(peer->public_key)) {
|
||||||
memcpy(peer->public_key, mnl_attr_get_payload(attr), sizeof(peer->public_key));
|
memcpy(peer->public_key, mnl_attr_get_payload(attr), sizeof(peer->public_key));
|
||||||
|
peer->flags |= WGPEER_HAS_PUBLIC_KEY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WGPEER_A_PRESHARED_KEY:
|
case WGPEER_A_PRESHARED_KEY:
|
||||||
if (mnl_attr_get_payload_len(attr) == sizeof(peer->preshared_key))
|
if (mnl_attr_get_payload_len(attr) == sizeof(peer->preshared_key)) {
|
||||||
memcpy(peer->preshared_key, mnl_attr_get_payload(attr), sizeof(peer->preshared_key));
|
memcpy(peer->preshared_key, mnl_attr_get_payload(attr), sizeof(peer->preshared_key));
|
||||||
|
if (!key_is_zero(peer->preshared_key))
|
||||||
|
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WGPEER_A_ENDPOINT: {
|
case WGPEER_A_ENDPOINT: {
|
||||||
struct sockaddr *addr;
|
struct sockaddr *addr;
|
||||||
|
@ -807,7 +814,7 @@ static int parse_peers(const struct nlattr *attr, void *data)
|
||||||
ret = mnl_attr_parse_nested(attr, parse_peer, new_peer);
|
ret = mnl_attr_parse_nested(attr, parse_peer, new_peer);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (key_is_zero(new_peer->public_key))
|
if (!(new_peer->flags & WGPEER_HAS_PUBLIC_KEY))
|
||||||
return MNL_CB_ERROR;
|
return MNL_CB_ERROR;
|
||||||
return MNL_CB_OK;
|
return MNL_CB_OK;
|
||||||
}
|
}
|
||||||
|
@ -828,12 +835,16 @@ static int parse_device(const struct nlattr *attr, void *data)
|
||||||
strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
|
strncpy(device->name, mnl_attr_get_str(attr), sizeof(device->name) - 1);
|
||||||
break;
|
break;
|
||||||
case WGDEVICE_A_PRIVATE_KEY:
|
case WGDEVICE_A_PRIVATE_KEY:
|
||||||
if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key))
|
if (mnl_attr_get_payload_len(attr) == sizeof(device->private_key)) {
|
||||||
memcpy(device->private_key, mnl_attr_get_payload(attr), sizeof(device->private_key));
|
memcpy(device->private_key, mnl_attr_get_payload(attr), sizeof(device->private_key));
|
||||||
|
device->flags |= WGDEVICE_HAS_PRIVATE_KEY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WGDEVICE_A_PUBLIC_KEY:
|
case WGDEVICE_A_PUBLIC_KEY:
|
||||||
if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key))
|
if (mnl_attr_get_payload_len(attr) == sizeof(device->public_key)) {
|
||||||
memcpy(device->public_key, mnl_attr_get_payload(attr), sizeof(device->public_key));
|
memcpy(device->public_key, mnl_attr_get_payload(attr), sizeof(device->public_key));
|
||||||
|
device->flags |= WGDEVICE_HAS_PUBLIC_KEY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WGDEVICE_A_LISTEN_PORT:
|
case WGDEVICE_A_LISTEN_PORT:
|
||||||
if (!mnl_attr_validate(attr, MNL_TYPE_U16))
|
if (!mnl_attr_validate(attr, MNL_TYPE_U16))
|
||||||
|
|
27
src/show.c
27
src/show.c
|
@ -67,12 +67,17 @@ static char *key(const uint8_t key[static WG_KEY_LEN])
|
||||||
{
|
{
|
||||||
static char base64[WG_KEY_LEN_BASE64];
|
static char base64[WG_KEY_LEN_BASE64];
|
||||||
|
|
||||||
if (key_is_zero(key))
|
|
||||||
return "(none)";
|
|
||||||
key_to_base64(base64, key);
|
key_to_base64(base64, key);
|
||||||
return base64;
|
return base64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *maybe_key(const uint8_t maybe_key[static WG_KEY_LEN], bool have_it)
|
||||||
|
{
|
||||||
|
if (!have_it)
|
||||||
|
return "(none)";
|
||||||
|
return key(maybe_key);
|
||||||
|
}
|
||||||
|
|
||||||
static char *masked_key(const uint8_t masked_key[static WG_KEY_LEN])
|
static char *masked_key(const uint8_t masked_key[static WG_KEY_LEN])
|
||||||
{
|
{
|
||||||
const char *var = getenv("WG_HIDE_KEYS");
|
const char *var = getenv("WG_HIDE_KEYS");
|
||||||
|
@ -201,9 +206,9 @@ static void pretty_print(struct wgdevice *device)
|
||||||
|
|
||||||
terminal_printf(TERMINAL_RESET);
|
terminal_printf(TERMINAL_RESET);
|
||||||
terminal_printf(TERMINAL_FG_GREEN TERMINAL_BOLD "interface" TERMINAL_RESET ": " TERMINAL_FG_GREEN "%s" TERMINAL_RESET "\n", device->name);
|
terminal_printf(TERMINAL_FG_GREEN TERMINAL_BOLD "interface" TERMINAL_RESET ": " TERMINAL_FG_GREEN "%s" TERMINAL_RESET "\n", device->name);
|
||||||
if (!key_is_zero(device->public_key))
|
if (device->flags & WGDEVICE_HAS_PUBLIC_KEY)
|
||||||
terminal_printf(" " TERMINAL_BOLD "public key" TERMINAL_RESET ": %s\n", key(device->public_key));
|
terminal_printf(" " TERMINAL_BOLD "public key" TERMINAL_RESET ": %s\n", key(device->public_key));
|
||||||
if (!key_is_zero(device->private_key))
|
if (device->flags & WGDEVICE_HAS_PRIVATE_KEY)
|
||||||
terminal_printf(" " TERMINAL_BOLD "private key" TERMINAL_RESET ": %s\n", masked_key(device->private_key));
|
terminal_printf(" " TERMINAL_BOLD "private key" TERMINAL_RESET ": %s\n", masked_key(device->private_key));
|
||||||
if (device->listen_port)
|
if (device->listen_port)
|
||||||
terminal_printf(" " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->listen_port);
|
terminal_printf(" " TERMINAL_BOLD "listening port" TERMINAL_RESET ": %u\n", device->listen_port);
|
||||||
|
@ -215,7 +220,7 @@ static void pretty_print(struct wgdevice *device)
|
||||||
}
|
}
|
||||||
for_each_wgpeer(device, peer) {
|
for_each_wgpeer(device, peer) {
|
||||||
terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));
|
terminal_printf(TERMINAL_FG_YELLOW TERMINAL_BOLD "peer" TERMINAL_RESET ": " TERMINAL_FG_YELLOW "%s" TERMINAL_RESET "\n", key(peer->public_key));
|
||||||
if (!key_is_zero(peer->preshared_key))
|
if (peer->flags & WGPEER_HAS_PRESHARED_KEY)
|
||||||
terminal_printf(" " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(peer->preshared_key));
|
terminal_printf(" " TERMINAL_BOLD "preshared key" TERMINAL_RESET ": %s\n", masked_key(peer->preshared_key));
|
||||||
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
|
if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6)
|
||||||
terminal_printf(" " TERMINAL_BOLD "endpoint" TERMINAL_RESET ": %s\n", endpoint(&peer->endpoint.addr));
|
terminal_printf(" " TERMINAL_BOLD "endpoint" TERMINAL_RESET ": %s\n", endpoint(&peer->endpoint.addr));
|
||||||
|
@ -246,8 +251,8 @@ static void dump_print(struct wgdevice *device, bool with_interface)
|
||||||
|
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->name);
|
printf("%s\t", device->name);
|
||||||
printf("%s\t", key(device->private_key));
|
printf("%s\t", maybe_key(device->private_key, device->flags & WGDEVICE_HAS_PRIVATE_KEY));
|
||||||
printf("%s\t", key(device->public_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->listen_port);
|
||||||
if (device->fwmark)
|
if (device->fwmark)
|
||||||
printf("0x%x\n", device->fwmark);
|
printf("0x%x\n", device->fwmark);
|
||||||
|
@ -257,7 +262,7 @@ static void dump_print(struct wgdevice *device, bool with_interface)
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->name);
|
printf("%s\t", device->name);
|
||||||
printf("%s\t", key(peer->public_key));
|
printf("%s\t", key(peer->public_key));
|
||||||
printf("%s\t", key(peer->preshared_key));
|
printf("%s\t", maybe_key(peer->preshared_key, peer->flags & WGPEER_HAS_PRESHARED_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\t", endpoint(&peer->endpoint.addr));
|
printf("%s\t", endpoint(&peer->endpoint.addr));
|
||||||
else
|
else
|
||||||
|
@ -284,11 +289,11 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
|
||||||
if (!strcmp(param, "public-key")) {
|
if (!strcmp(param, "public-key")) {
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->name);
|
printf("%s\t", device->name);
|
||||||
printf("%s\n", key(device->public_key));
|
printf("%s\n", maybe_key(device->public_key, device->flags & WGDEVICE_HAS_PUBLIC_KEY));
|
||||||
} else if (!strcmp(param, "private-key")) {
|
} else if (!strcmp(param, "private-key")) {
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->name);
|
printf("%s\t", device->name);
|
||||||
printf("%s\n", key(device->private_key));
|
printf("%s\n", maybe_key(device->private_key, device->flags & WGDEVICE_HAS_PRIVATE_KEY));
|
||||||
} else if (!strcmp(param, "listen-port")) {
|
} else if (!strcmp(param, "listen-port")) {
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->name);
|
printf("%s\t", device->name);
|
||||||
|
@ -347,7 +352,7 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int
|
||||||
if (with_interface)
|
if (with_interface)
|
||||||
printf("%s\t", device->name);
|
printf("%s\t", device->name);
|
||||||
printf("%s\t", key(peer->public_key));
|
printf("%s\t", key(peer->public_key));
|
||||||
printf("%s\n", key(peer->preshared_key));
|
printf("%s\n", maybe_key(peer->preshared_key, peer->flags & WGPEER_HAS_PRESHARED_KEY));
|
||||||
}
|
}
|
||||||
} else if (!strcmp(param, "peers")) {
|
} else if (!strcmp(param, "peers")) {
|
||||||
for_each_wgpeer(device, peer) {
|
for_each_wgpeer(device, peer) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ int showconf_main(int argc, char *argv[])
|
||||||
printf("ListenPort = %u\n", device->listen_port);
|
printf("ListenPort = %u\n", device->listen_port);
|
||||||
if (device->fwmark)
|
if (device->fwmark)
|
||||||
printf("FwMark = 0x%x\n", device->fwmark);
|
printf("FwMark = 0x%x\n", device->fwmark);
|
||||||
if (!key_is_zero(device->private_key)) {
|
if (device->flags & WGDEVICE_HAS_PRIVATE_KEY) {
|
||||||
key_to_base64(base64, device->private_key);
|
key_to_base64(base64, device->private_key);
|
||||||
printf("PrivateKey = %s\n", base64);
|
printf("PrivateKey = %s\n", base64);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ int showconf_main(int argc, char *argv[])
|
||||||
for_each_wgpeer(device, peer) {
|
for_each_wgpeer(device, peer) {
|
||||||
key_to_base64(base64, peer->public_key);
|
key_to_base64(base64, peer->public_key);
|
||||||
printf("[Peer]\nPublicKey = %s\n", base64);
|
printf("[Peer]\nPublicKey = %s\n", base64);
|
||||||
if (!key_is_zero(peer->preshared_key)) {
|
if (peer->flags & WGPEER_HAS_PRESHARED_KEY) {
|
||||||
key_to_base64(base64, peer->preshared_key);
|
key_to_base64(base64, peer->preshared_key);
|
||||||
printf("PresharedKey = %s\n", base64);
|
printf("PresharedKey = %s\n", base64);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue