From 7a989b36d186e5a22763a61c9541ae202e2c0ba8 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 11 Nov 2017 12:30:21 +0900 Subject: tools: allow for NULL keys everywhere --- src/tools/config.c | 13 ++++++++----- src/tools/containers.h | 10 ++++++---- src/tools/ipc.c | 25 ++++++++++++++++++------- src/tools/show.c | 27 ++++++++++++++++----------- src/tools/showconf.c | 4 ++-- 5 files changed, 50 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/tools/config.c b/src/tools/config.c index 5b25b46..540b800 100644 --- a/src/tools/config.c +++ b/src/tools/config.c @@ -318,9 +318,11 @@ static bool process_line(struct config_ctx *ctx, const char *line) } else if (ctx->is_peer_section) { if (key_match("Endpoint")) 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); - 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); else if (key_match("PersistentKeepalive")) 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); if (!ret) 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; } else goto error; @@ -390,7 +392,7 @@ struct wgdevice *config_read_finish(struct config_ctx *ctx) struct wgpeer *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"); goto err; } @@ -548,7 +550,8 @@ struct wgdevice *config_read_cmd(char *argv[], int argc) if (read_keyfile(key_line, argv[1])) { if (!parse_key(peer->preshared_key, key_line)) goto error; - peer->flags |= WGPEER_HAS_PRESHARED_KEY; + if (!key_is_zero(peer->preshared_key)) + peer->flags |= WGPEER_HAS_PRESHARED_KEY; } else goto error; argv += 2; diff --git a/src/tools/containers.h b/src/tools/containers.h index c35465e..58d0657 100644 --- a/src/tools/containers.h +++ b/src/tools/containers.h @@ -26,8 +26,9 @@ struct wgallowedip { enum { WGPEER_REMOVE_ME = 1U << 0, WGPEER_REPLACE_ALLOWEDIPS = 1U << 1, - WGPEER_HAS_PRESHARED_KEY = 1U << 2, - WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 3 + WGPEER_HAS_PUBLIC_KEY = 1U << 2, + WGPEER_HAS_PRESHARED_KEY = 1U << 3, + WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4 }; struct wgpeer { @@ -53,8 +54,9 @@ struct wgpeer { enum { WGDEVICE_REPLACE_PEERS = 1U << 0, WGDEVICE_HAS_PRIVATE_KEY = 1U << 1, - WGDEVICE_HAS_LISTEN_PORT = 1U << 2, - WGDEVICE_HAS_FWMARK = 1U << 3 + WGDEVICE_HAS_PUBLIC_KEY = 1U << 2, + WGDEVICE_HAS_LISTEN_PORT = 1U << 3, + WGDEVICE_HAS_FWMARK = 1U << 4 }; struct wgdevice { diff --git a/src/tools/ipc.c b/src/tools/ipc.c index d67ada2..0f87d24 100644 --- a/src/tools/ipc.c +++ b/src/tools/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)) break; 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")) { dev->listen_port = NUM(0xffffU); dev->flags |= WGDEVICE_HAS_LISTEN_PORT; @@ -350,10 +350,12 @@ static int userspace_get_device(struct wgdevice **out, const char *interface) peer = new_peer; if (!key_from_hex(peer->public_key, value)) break; + peer->flags |= WGPEER_HAS_PUBLIC_KEY; } else if (peer && !strcmp(key, "preshared_key")) { if (!key_from_hex(peer->preshared_key, value)) 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")) { char *begin, *end; struct addrinfo *resolved; @@ -744,12 +746,17 @@ static int parse_peer(const struct nlattr *attr, void *data) case WGPEER_A_UNSPEC: break; 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)); + peer->flags |= WGPEER_HAS_PUBLIC_KEY; + } break; 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)); + if (!key_is_zero(peer->preshared_key)) + peer->flags |= WGPEER_HAS_PRESHARED_KEY; + } break; case WGPEER_A_ENDPOINT: { 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); if (!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_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); break; 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)); + device->flags |= WGDEVICE_HAS_PRIVATE_KEY; + } break; 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)); + device->flags |= WGDEVICE_HAS_PUBLIC_KEY; + } break; case WGDEVICE_A_LISTEN_PORT: if (!mnl_attr_validate(attr, MNL_TYPE_U16)) diff --git a/src/tools/show.c b/src/tools/show.c index 05777b1..6ae5830 100644 --- a/src/tools/show.c +++ b/src/tools/show.c @@ -67,12 +67,17 @@ static char *key(const uint8_t key[static WG_KEY_LEN]) { static char base64[WG_KEY_LEN_BASE64]; - if (key_is_zero(key)) - return "(none)"; key_to_base64(base64, key); 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]) { 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_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)); - 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)); if (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) { 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)); 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)); @@ -246,8 +251,8 @@ static void dump_print(struct wgdevice *device, bool with_interface) if (with_interface) printf("%s\t", device->name); - printf("%s\t", key(device->private_key)); - printf("%s\t", key(device->public_key)); + 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); if (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) printf("%s\t", device->name); 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) printf("%s\t", endpoint(&peer->endpoint.addr)); else @@ -284,11 +289,11 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int if (!strcmp(param, "public-key")) { if (with_interface) 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")) { if (with_interface) 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")) { if (with_interface) 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) printf("%s\t", device->name); 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")) { for_each_wgpeer(device, peer) { diff --git a/src/tools/showconf.c b/src/tools/showconf.c index 2843910..e780d78 100644 --- a/src/tools/showconf.c +++ b/src/tools/showconf.c @@ -38,7 +38,7 @@ int showconf_main(int argc, char *argv[]) printf("ListenPort = %u\n", device->listen_port); if (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); printf("PrivateKey = %s\n", base64); } @@ -46,7 +46,7 @@ int showconf_main(int argc, char *argv[]) for_each_wgpeer(device, peer) { key_to_base64(base64, peer->public_key); 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); printf("PresharedKey = %s\n", base64); } -- cgit v1.2.3-59-g8ed1b