Skip to content

Commit

Permalink
Support for legacy clients
Browse files Browse the repository at this point in the history
  • Loading branch information
leninalive committed Sep 3, 2024
1 parent e42813c commit dafa38e
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 4 deletions.
4 changes: 3 additions & 1 deletion contrib/embeddable-wg-library/wireguard.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ enum wgdevice_attribute {

enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1U << 0,
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
WGPEER_F_HAS_ADVANCED_SECURITY = 1U << 3
};
enum wgpeer_attribute {
WGPEER_A_UNSPEC,
Expand All @@ -76,6 +77,7 @@ enum wgpeer_attribute {
WGPEER_A_TX_BYTES,
WGPEER_A_ALLOWEDIPS,
WGPEER_A_PROTOCOL_VERSION,
WGPEER_A_ADVANCED_SECURITY,
__WGPEER_A_LAST
};

Expand Down
45 changes: 45 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,41 @@ static inline bool parse_uint32(uint32_t *device_value, const char *name, const
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;
Expand Down Expand Up @@ -540,6 +575,10 @@ static bool process_line(struct config_ctx *ctx, const char *line)
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
Expand Down Expand Up @@ -774,6 +813,12 @@ struct wgdevice *config_read_cmd(const char *argv[], int argc)
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;
Expand Down
8 changes: 6 additions & 2 deletions src/containers.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define CONTAINERS_H

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
Expand Down Expand Up @@ -43,7 +44,8 @@ enum {
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 {
Expand All @@ -62,6 +64,8 @@ struct wgpeer {
uint64_t rx_bytes, tx_bytes;
uint16_t persistent_keepalive_interval;

bool advanced_security;

struct wgallowedip *first_allowedip, *last_allowedip;
struct wgpeer *next_peer;
};
Expand Down Expand Up @@ -96,7 +100,7 @@ struct wgdevice {
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;
Expand Down
24 changes: 24 additions & 0 deletions src/ipc-linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ static int kernel_set_device(struct wgdevice *dev)
goto toobig_peers;
}
}
if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
if (peer->advanced_security)
mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ADVANCED_SECURITY, 0, NULL);
flags |= WGPEER_F_HAS_ADVANCED_SECURITY;
}
if (flags) {
if (!mnl_attr_put_u32_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_FLAGS, flags))
goto toobig_peers;
Expand Down Expand Up @@ -389,6 +394,25 @@ static int parse_peer(const struct nlattr *attr, void *data)
if (!mnl_attr_validate(attr, MNL_TYPE_U64))
peer->tx_bytes = mnl_attr_get_u64(attr);
break;
case WGPEER_A_FLAGS:
if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {
uint32_t flags = mnl_attr_get_u32(attr);

if (flags & WGPEER_F_HAS_ADVANCED_SECURITY && !(peer->flags & WGPEER_HAS_ADVANCED_SECURITY)) {
peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
peer->advanced_security = false;
}
}
break;
case WGPEER_A_ADVANCED_SECURITY:
if (!mnl_attr_validate(attr, MNL_TYPE_FLAG)) {
peer->advanced_security = true;

if (!(peer->flags & WGPEER_HAS_ADVANCED_SECURITY)) {
peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
}
}
break;
case WGPEER_A_ALLOWEDIPS:
return mnl_attr_parse_nested(attr, parse_allowedips, peer);
}
Expand Down
4 changes: 4 additions & 0 deletions src/ipc-uapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ static int userspace_set_device(struct wgdevice *dev)
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;
Expand Down
2 changes: 1 addition & 1 deletion src/set.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ int set_main(int argc, const char *argv[])
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;
}

Expand Down
3 changes: 3 additions & 0 deletions src/showconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ int showconf_main(int argc, const char *argv[])
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) {
Expand Down
5 changes: 5 additions & 0 deletions src/uapi/linux/linux/wireguard.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
* most recent protocol will be used when
* this is unset. Otherwise, must be set
* to 1.
* WGPEER_A_ADVANCED_SECURITY: flag indicating that advanced security
* techniques provided by AmneziaWG should
* be used.
* 0: NLA_NESTED
* ...
* ...
Expand Down Expand Up @@ -174,6 +177,7 @@ enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1U << 0,
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
WGPEER_F_UPDATE_ONLY = 1U << 2,
WGPEER_F_HAS_ADVANCED_SECURITY = 1U << 3,
__WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS |
WGPEER_F_UPDATE_ONLY
};
Expand All @@ -189,6 +193,7 @@ enum wgpeer_attribute {
WGPEER_A_TX_BYTES,
WGPEER_A_ALLOWEDIPS,
WGPEER_A_PROTOCOL_VERSION,
WGPEER_A_ADVANCED_SECURITY,
__WGPEER_A_LAST
};
#define WGPEER_A_MAX (__WGPEER_A_LAST - 1)
Expand Down

0 comments on commit dafa38e

Please sign in to comment.