]> git.ipfire.org Git - thirdparty/wireguard-tools.git/commitdiff
wg: allow for NULL keys everywhere
authorJason A. Donenfeld <Jason@zx2c4.com>
Sat, 11 Nov 2017 03:30:21 +0000 (12:30 +0900)
committerJason A. Donenfeld <Jason@zx2c4.com>
Sat, 11 Nov 2017 03:30:49 +0000 (12:30 +0900)
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
src/config.c
src/containers.h
src/ipc.c
src/show.c
src/showconf.c

index 5b25b460ae3a8537cedb8dae56b5c009f015c778..540b800d8eaa4751c064ea9c890586d168519a91 100644 (file)
@@ -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;
index c35465e9c3f4b5a3dff5bb7ff5c6e28304de9b6a..58d06579c51decc4629114d209560a7f2babb01b 100644 (file)
@@ -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 {
index d67ada23b015bcf18fa6672878d1c3ee2b1d3375..0f87d2472d0107581a6321d856bc2b1ccd75e1f6 100644 (file)
--- a/src/ipc.c
+++ b/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))
                                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))
index 05777b1c9034caef06982044060c3462e7ded493..6ae583008b16782dfc6c8874bc0faddbe453030f 100644 (file)
@@ -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) {
index 284391057ad22350042688f6099752955a21a6ac..e780d784b8e7de3888d008bd808dbe949d7ee9e8 100644 (file)
@@ -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);
                }