From 211a6d196ab977113f6e35fd64f8f66bc94fb19c Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Tue, 15 Jul 2025 05:12:12 +0200 Subject: [PATCH 1/8] Revert "Merge pull request #29 from amnezia-vpn/revert-25-awg-1.5" This reverts commit 2b593ee0860e2ecc7cfcbfab4261194256329048, reversing changes made to ae857090cdef53919ed197c477869544780fc6eb. --- contrib/embeddable-wg-library/wireguard.c | 15 +- contrib/json/wg-json | 11 +- contrib/peer-approver/approve.sh | 3 +- contrib/peer-approver/notification-listener.c | 21 +- src/config.c | 221 ++++++++++++++++-- src/containers.h | 38 ++- src/ipc-freebsd.h | 167 +++++++++++-- src/ipc-linux.h | 122 ++++++++++ src/ipc-openbsd.h | 130 ++++++++++- src/ipc-uapi.h | 69 ++++++ src/ipc-windows.h | 139 +++++++++++ src/set.c | 2 +- src/show.c | 71 +++++- src/showconf.c | 25 ++ src/uapi/linux/linux/wireguard.h | 19 ++ src/uapi/openbsd/net/if_wg.h | 47 +++- src/uapi/windows/wireguard.h | 31 ++- src/wg-quick/android.c | 23 +- src/wg.c | 2 +- 19 files changed, 1079 insertions(+), 77 deletions(-) diff --git a/contrib/embeddable-wg-library/wireguard.c b/contrib/embeddable-wg-library/wireguard.c index 500f33d..26de0e9 100644 --- a/contrib/embeddable-wg-library/wireguard.c +++ b/contrib/embeddable-wg-library/wireguard.c @@ -53,17 +53,29 @@ enum wgdevice_attribute { WGDEVICE_A_JMAX, WGDEVICE_A_S1, WGDEVICE_A_S2, + WGDEVICE_A_S3, + WGDEVICE_A_S4, WGDEVICE_A_H1, WGDEVICE_A_H2, WGDEVICE_A_H3, WGDEVICE_A_H4, + WGDEVICE_A_I1, + WGDEVICE_A_I2, + WGDEVICE_A_I3, + WGDEVICE_A_I4, + WGDEVICE_A_I5, + WGDEVICE_A_J1, + WGDEVICE_A_J2, + WGDEVICE_A_J3, + WGDEVICE_A_ITIME, __WGDEVICE_A_LAST }; enum wgpeer_flag { WGPEER_F_REMOVE_ME = 1U << 0, WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1, - WGPEER_F_HAS_ADVANCED_SECURITY = 1U << 3 + WGPEER_F_HAS_ADVANCED_SECURITY = 1U << 3, + WGPEER_F_HAS_SPECIAL_HANDSHAKE = 1U << 4 }; enum wgpeer_attribute { WGPEER_A_UNSPEC, @@ -78,6 +90,7 @@ enum wgpeer_attribute { WGPEER_A_ALLOWEDIPS, WGPEER_A_PROTOCOL_VERSION, WGPEER_A_ADVANCED_SECURITY, + WGPEER_A_SPECIAL_HANDSHAKE, __WGPEER_A_LAST }; diff --git a/contrib/json/wg-json b/contrib/json/wg-json index 83ab135..d24296a 100755 --- a/contrib/json/wg-json +++ b/contrib/json/wg-json @@ -11,7 +11,7 @@ while read -r -d $'\t' device; do if [[ $device != "$last_device" ]]; then [[ -z $last_device ]] && printf '\n' || printf '%s,\n' "$end" last_device="$device" - read -r private_key public_key listen_port jc jmin jmax s1 s2 h1 h2 h3 h4 fwmark + read -r private_key public_key listen_port jc jmin jmax s1 s2 h1 h2 h3 h4 i1 i2 i3 i4 i5 j1 j2 j3 itime fwmark printf '\t"%s": {' "$device" delim=$'\n' [[ $private_key == "(none)" ]] || { printf '%s\t\t"privateKey": "%s"' "$delim" "$private_key"; delim=$',\n'; } @@ -26,6 +26,15 @@ while read -r -d $'\t' device; do [[ $h2 == "2" ]] || { printf '%s\t\t"h2": %u' "$delim" $(( $h2 )); delim=$',\n'; } [[ $h3 == "3" ]] || { printf '%s\t\t"h3": %u' "$delim" $(( $h3 )); delim=$',\n'; } [[ $h4 == "4" ]] || { printf '%s\t\t"h4": %u' "$delim" $(( $h4 )); delim=$',\n'; } + [[ $i1 == "(none)" ]] || { printf '%s\t\t"i1": "%s"' "$delim" "$i1"; delim=$',\n'; } + [[ $i2 == "(none)" ]] || { printf '%s\t\t"i2": "%s"' "$delim" "$i2"; delim=$',\n'; } + [[ $i3 == "(none)" ]] || { printf '%s\t\t"i3": "%s"' "$delim" "$i3"; delim=$',\n'; } + [[ $i4 == "(none)" ]] || { printf '%s\t\t"i4": "%s"' "$delim" "$i4"; delim=$',\n'; } + [[ $i5 == "(none)" ]] || { printf '%s\t\t"i5": "%s"' "$delim" "$i5"; delim=$',\n'; } + [[ $j1 == "(none)" ]] || { printf '%s\t\t"j1": "%s"' "$delim" "$j1"; delim=$',\n'; } + [[ $j2 == "(none)" ]] || { printf '%s\t\t"j2": "%s"' "$delim" "$j2"; delim=$',\n'; } + [[ $j3 == "(none)" ]] || { printf '%s\t\t"j3": "%s"' "$delim" "$j3"; delim=$',\n'; } + [[ $itime == "0" ]] || { printf '%s\t\t"itime": %u' "$delim" $(( itime )); delim=$',\n'; } [[ $fwmark == "off" ]] || { printf '%s\t\t"fwmark": %u' "$delim" $(( $fwmark )); delim=$',\n'; } printf '%s\t\t"peers": {' "$delim"; end=$'\n\t\t}\n\t}' delim=$'\n' diff --git a/contrib/peer-approver/approve.sh b/contrib/peer-approver/approve.sh index b4ecfe9..e711a6c 100755 --- a/contrib/peer-approver/approve.sh +++ b/contrib/peer-approver/approve.sh @@ -5,6 +5,7 @@ INTERFACE_NAME=$2 PUBLIC_KEY=$3 ENDPOINT=$4 ADVANCED_SECURITY=$5 +SPECIAL_HANDSHAKE=$6 ACCOUNT_STR=`grep "${PUBLIC_KEY}" "${ACCOUNTS_FILE}"` @@ -19,7 +20,7 @@ PSK=$(echo ${ACCOUNT[2]}|tr -d '"') PSK_FILE=$(tempfile) echo "${PSK}" > "${PSK_FILE}" -awg set "${INTERFACE_NAME}" peer "${PUBLIC_KEY}" allowed-ips "${ALLOWED_IPS}" endpoint "${ENDPOINT}" allowed-ips "${ALLOWED_IPS}" preshared-key "${PSK_FILE}" advanced-security "${ADVANCED_SECURITY}" +awg set "${INTERFACE_NAME}" peer "${PUBLIC_KEY}" allowed-ips "${ALLOWED_IPS}" endpoint "${ENDPOINT}" allowed-ips "${ALLOWED_IPS}" preshared-key "${PSK_FILE}" advanced-security "${ADVANCED_SECURITY}" special-handshake "${SPECIAL_HANDSHAKE}" EXIT_CODE=$? rm -f "{$PSK_FILE}" diff --git a/contrib/peer-approver/notification-listener.c b/contrib/peer-approver/notification-listener.c index a264673..0057e71 100644 --- a/contrib/peer-approver/notification-listener.c +++ b/contrib/peer-approver/notification-listener.c @@ -116,18 +116,19 @@ static int get_endpoint(struct nlattr *peer[], char **endpoint_ip) return 0; } -static int run_callback(char *ifname, char *pubkey, char *endpoint_ip, bool advanced_security) +static int run_callback(char *ifname, char *pubkey, char *endpoint_ip, bool advanced_security, bool special_handshake) { char** new_argv = malloc((cb_argc + 2) * sizeof *new_argv); new_argv[0] = cb_argv[1]; - for (int i = 2; i < cb_argc - 3; i++) { + for (int i = 2; i < cb_argc - 4; i++) { new_argv[i - 1] = cb_argv[i]; } - new_argv[cb_argc - 4] = ifname; - new_argv[cb_argc - 3] = pubkey; - new_argv[cb_argc - 2] = endpoint_ip; - new_argv[cb_argc - 1] = (advanced_security ? "on\0" : "off\0"); + new_argv[cb_argc - 5] = ifname; + new_argv[cb_argc - 4] = pubkey; + new_argv[cb_argc - 3] = endpoint_ip; + new_argv[cb_argc - 2] = (advanced_security ? "on\0" : "off\0"); + new_argv[cb_argc - 1] = (special_handshake ? "on\0" : "off\0"); new_argv[cb_argc] = NULL; int child_pid = fork(), ret; @@ -156,6 +157,7 @@ static int netlink_callback(struct nl_msg *msg, void *arg) char *ifname, *pubkey, *endpoint_ip; bool advanced_security = false; + bool special_handshake = false; int cb_ret; switch (gnlh->cmd) { @@ -179,7 +181,10 @@ static int netlink_callback(struct nl_msg *msg, void *arg) if (nla_get_flag(peer[WGPEER_A_ADVANCED_SECURITY])) { advanced_security = true; } - if (cb_ret = run_callback(ifname, pubkey, endpoint_ip, advanced_security)) { + if (nla_get_flag(peer[WGPEER_A_SPECIAL_HANDSHAKE])) { + special_handshake = true; + } + if (cb_ret = run_callback(ifname, pubkey, endpoint_ip, advanced_security, special_handshake)) { prerr("failed to execute callback script: %d!\n", cb_ret); return NL_SKIP; } @@ -260,4 +265,4 @@ int main(int argc, char *argv[]) } cleanup_and_exit(EXIT_FAILURE); -} \ No newline at end of file +} diff --git a/src/config.c b/src/config.c index f663b7d..a2b35f1 100644 --- a/src/config.c +++ b/src/config.c @@ -22,6 +22,13 @@ #define COMMENT_CHAR '#' +// Keys that should return empty string instead of NULL when not found +static const char *awg_optional_keys[] = { + "I1", "I2", "I3", "I4", "I5", + "J1", "J2", "J3", + NULL +}; + static const char *get_value(const char *line, const char *key) { size_t linelen = strlen(line); @@ -33,6 +40,7 @@ static const char *get_value(const char *line, const char *key) if (strncasecmp(line, key, keylen)) return NULL; + return line + keylen; } @@ -410,13 +418,29 @@ err: return false; } +static inline bool parse_awg_string(char **device_value, const char *name, const char *value) { + size_t len = strlen(value); + if (!len) { + *device_value = ""; + return true; + } + + if( len >= MAX_AWG_JUNK_LEN) { + fprintf(stderr, "Unable to process string for: %s; longer than: %d\n", name, MAX_AWG_JUNK_LEN); + return false; + } + *device_value = strdup(value); + + return true; +} + static inline bool parse_uint16(uint16_t *device_value, const char *name, const char *value) { if (!strlen(value)) { fprintf(stderr, "Unable to parse empty string\n"); return false; } - + char *end; uint32_t ret; ret = strtoul(value, &end, 10); @@ -542,6 +566,14 @@ static bool process_line(struct config_ctx *ctx, const char *line) ret = parse_uint16(&ctx->device->response_packet_junk_size, "S2", value); if (ret) ctx->device->flags |= WGDEVICE_HAS_S2; + } else if (key_match("S3")) { + ret = parse_uint16(&ctx->device->cookie_reply_packet_junk_size, "S3", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_S3; + } else if (key_match("S4")) { + ret = parse_uint16(&ctx->device->transport_packet_junk_size, "S4", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_S4; } else if (key_match("H1")) { ret = parse_uint32(&ctx->device->init_packet_magic_header, "H1", value); if (ret) @@ -558,8 +590,52 @@ static bool process_line(struct config_ctx *ctx, const char *line) ret = parse_uint32(&ctx->device->transport_packet_magic_header, "H4", value); if (ret) ctx->device->flags |= WGDEVICE_HAS_H4; - } else + } else if (key_match("I1")) { + ret = parse_awg_string(&ctx->device->i1, "I1", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_I1; + } else if (key_match("I2")) { + ret = parse_awg_string(&ctx->device->i2, "I2", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_I2; + } else if (key_match("I3")) { + ret = parse_awg_string(&ctx->device->i3, "I3", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_I3; + } else if (key_match("I4")) { + ret = parse_awg_string(&ctx->device->i4, "I4", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_I4; + } else if (key_match("I5")) { + ret = parse_awg_string(&ctx->device->i5, "I5", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_I5; + } else if (key_match("J1")) { + ret = parse_awg_string(&ctx->device->j1, "J1", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_J1; + } else if (key_match("J2")) { + ret = parse_awg_string(&ctx->device->j2, "J2", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_J2; + } else if (key_match("J3")) { + ret = parse_awg_string(&ctx->device->j3, "J3", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_J3; + } else if (key_match("Itime")) { + ret = parse_uint32(&ctx->device->itime, "Itime", value); + if (ret) + ctx->device->flags |= WGDEVICE_HAS_ITIME; + } else { + // Check if this is an AWG optional key + if (strlen(line) == 3) { + for (int i = 0; awg_optional_keys[i] != NULL; i++) { + if (!strncasecmp(line, awg_optional_keys[i], 2)) + return true; + } + } goto error; + } } else if (ctx->is_peer_section) { if (key_match("Endpoint")) ret = parse_endpoint(&ctx->last_peer->endpoint.addr, value); @@ -579,6 +655,10 @@ static bool process_line(struct config_ctx *ctx, const char *line) ret = parse_bool(&ctx->last_peer->advanced_security, "AdvancedSecurity", value); if (ret) ctx->last_peer->flags |= WGPEER_HAS_ADVANCED_SECURITY; + } else if (key_match("SpecialHandshake")) { + ret = parse_bool(&ctx->last_peer->special_handshake, "SpecialHandshake", value); + if (ret) + ctx->last_peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; } else goto error; } else @@ -597,6 +677,9 @@ bool config_read_line(struct config_ctx *ctx, const char *input) size_t len, cleaned_len = 0; char *line, *comment; bool ret = true; + bool found_equals = false; + bool found_value_start = false; + size_t value_end = 0; /* This is what strchrnul is for, but that isn't portable. */ comment = strchr(input, COMMENT_CHAR); @@ -612,10 +695,37 @@ bool config_read_line(struct config_ctx *ctx, const char *input) goto out; } - for (size_t i = 0; i < len; ++i) { - if (!char_is_space(input[i])) - line[cleaned_len++] = input[i]; + /* Remove preceding and trailing whitespaces before value + First pass: find the actual end of the value (trim trailing spaces) */ + for (size_t i = len; i > 0; --i) { + if (!char_is_space(input[i - 1])) { + value_end = i; + break; + } } + + /* Second pass: clean according to KEY = VALUE rules */ + for (size_t i = 0; i < value_end; ++i) { + if (!found_equals) { + /* Before '=': remove all whitespace */ + if (input[i] == '=') { + line[cleaned_len++] = input[i]; + found_equals = true; + } else if (!char_is_space(input[i])) { + line[cleaned_len++] = input[i]; + } + } else if (!found_value_start) { + /* After '=' but before value: skip whitespace until first non-space */ + if (!char_is_space(input[i])) { + line[cleaned_len++] = input[i]; + found_value_start = true; + } + } else { + /* Within value: preserve all characters including spaces */ + line[cleaned_len++] = input[i]; + } + } + if (!cleaned_len) goto out; ret = process_line(ctx, line); @@ -703,66 +813,143 @@ struct wgdevice *config_read_cmd(const char *argv[], int argc) } else if (!strcmp(argv[0], "jc") && argc >= 2 && !peer) { if (!parse_uint16(&device->junk_packet_count, "jc", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_JC; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "jmin") && argc >= 2 && !peer) { if (!parse_uint16(&device->junk_packet_min_size, "jmin", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_JMIN; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "jmax") && argc >= 2 && !peer) { if (!parse_uint16(&device->junk_packet_max_size, "jmax", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_JMAX; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "s1") && argc >= 2 && !peer) { if (!parse_uint16(&device->init_packet_junk_size, "s1", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_S1; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "s2") && argc >= 2 && !peer) { if (!parse_uint16(&device->response_packet_junk_size, "s2", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_S2; argv += 2; argc -= 2; + } else if (!strcmp(argv[0], "s3") && argc >= 2 && !peer) { + if (!parse_uint16(&device->cookie_reply_packet_junk_size, "s3", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_S3; + argv += 2; + argc -= 2; + } else if (!strcmp(argv[0], "s4") && argc >= 2 && !peer) { + if (!parse_uint16(&device->transport_packet_junk_size, "s4", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_S4; + argv += 2; + argc -= 2; } else if (!strcmp(argv[0], "h1") && argc >= 2 && !peer) { if (!parse_uint32(&device->init_packet_magic_header, "h1", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_H1; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "h2") && argc >= 2 && !peer) { if (!parse_uint32(&device->response_packet_magic_header, "h2", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_H2; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "h3") && argc >= 2 && !peer) { if (!parse_uint32(&device->underload_packet_magic_header, "h3", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_H3; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "h4") && argc >= 2 && !peer) { if (!parse_uint32(&device->transport_packet_magic_header, "h4", argv[1])) goto error; - + device->flags |= WGDEVICE_HAS_H4; argv += 2; argc -= 2; + } else if (!strcmp(argv[0], "i1") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->i1, "i1", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_I1; + argv += 2; + argc -= 2; + } else if (!strcmp(argv[0], "i2") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->i2, "i2", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_I2; + argv += 2; + argc -=2; + } else if (!strcmp(argv[0], "i3") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->i3, "i3", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_I3; + argv += 2; + argc -=2; + } else if (!strcmp(argv[0], "i4") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->i4, "i4", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_I4; + argv += 2; + argc -=2; + } else if (!strcmp(argv[0], "i5") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->i5, "i5", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_I5; + argv += 2; + argc -=2; + } else if (!strcmp(argv[0], "j1") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->j1, "j1", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_J1; + argv += 2; + argc -=2; + } else if (!strcmp(argv[0], "j2") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->j2, "j2", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_J2; + argv += 2; + argc -=2; + } else if (!strcmp(argv[0], "j3") && argc >= 2 && !peer) { + if (!parse_awg_string(&device->j3, "j3", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_J3; + argv += 2; + argc -=2; + } else if (!strcmp(argv[0], "itime") && argc >= 2 && !peer) { + if (!parse_uint32(&device->itime, "itime", argv[1])) + goto error; + + device->flags |= WGDEVICE_HAS_ITIME; + argv += 2; + argc -=2; } else if (!strcmp(argv[0], "peer") && argc >= 2) { struct wgpeer *new_peer = calloc(1, sizeof(*new_peer)); @@ -819,6 +1006,12 @@ struct wgdevice *config_read_cmd(const char *argv[], int argc) peer->flags |= WGPEER_HAS_ADVANCED_SECURITY; argv += 2; argc -= 2; + } else if (!strcmp(argv[0], "special-handshake") && argc >= 2 && peer) { + if (!parse_bool(&peer->special_handshake, "SpecialHandshake", argv[1])) + goto error; + peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; + argv += 2; + argc -= 2; } else { fprintf(stderr, "Invalid argument: %s\n", argv[0]); goto error; diff --git a/src/containers.h b/src/containers.h index 8f93bb5..09ff619 100644 --- a/src/containers.h +++ b/src/containers.h @@ -23,6 +23,10 @@ #define WG_KEY_LEN 32 #endif +#ifndef MAX_AWG_JUNK_LEN +#define MAX_AWG_JUNK_LEN 5 * 1024 +#endif + /* Cross platform __kernel_timespec */ struct timespec64 { int64_t tv_sec; @@ -45,7 +49,8 @@ enum { WGPEER_HAS_PUBLIC_KEY = 1U << 2, WGPEER_HAS_PRESHARED_KEY = 1U << 3, WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4, - WGPEER_HAS_ADVANCED_SECURITY = 1U << 5 + WGPEER_HAS_ADVANCED_SECURITY = 1U << 5, + WGPEER_HAS_SPECIAL_HANDSHAKE = 1U << 6 }; struct wgpeer { @@ -65,6 +70,7 @@ struct wgpeer { uint16_t persistent_keepalive_interval; bool advanced_security; + bool special_handshake; struct wgallowedip *first_allowedip, *last_allowedip; struct wgpeer *next_peer; @@ -81,10 +87,21 @@ enum { WGDEVICE_HAS_JMAX = 1U << 7, WGDEVICE_HAS_S1 = 1U << 8, WGDEVICE_HAS_S2 = 1U << 9, - WGDEVICE_HAS_H1 = 1U << 10, - WGDEVICE_HAS_H2 = 1U << 11, - WGDEVICE_HAS_H3 = 1U << 12, - WGDEVICE_HAS_H4 = 1U << 13 + WGDEVICE_HAS_S3 = 1U << 10, + WGDEVICE_HAS_S4 = 1U << 11, + WGDEVICE_HAS_H1 = 1U << 12, + WGDEVICE_HAS_H2 = 1U << 12, + WGDEVICE_HAS_H3 = 1U << 13, + WGDEVICE_HAS_H4 = 1U << 14, + WGDEVICE_HAS_I1 = 1U << 15, + WGDEVICE_HAS_I2 = 1U << 16, + WGDEVICE_HAS_I3 = 1U << 17, + WGDEVICE_HAS_I4 = 1U << 18, + WGDEVICE_HAS_I5 = 1U << 19, + WGDEVICE_HAS_J1 = 1U << 20, + WGDEVICE_HAS_J2 = 1U << 21, + WGDEVICE_HAS_J3 = 1U << 22, + WGDEVICE_HAS_ITIME = 1U << 23 }; struct wgdevice { @@ -106,10 +123,21 @@ struct wgdevice { uint16_t junk_packet_max_size; uint16_t init_packet_junk_size; uint16_t response_packet_junk_size; + uint16_t cookie_reply_packet_junk_size; + uint16_t transport_packet_junk_size; uint32_t init_packet_magic_header; uint32_t response_packet_magic_header; uint32_t underload_packet_magic_header; uint32_t transport_packet_magic_header; + char* i1; + char* i2; + char* i3; + char* i4; + char* i5; + char* j1; + char* j2; + char* j3; + uint32_t itime; }; #define for_each_wgpeer(__dev, __peer) for ((__peer) = (__dev)->first_peer; (__peer); (__peer) = (__peer)->next_peer) diff --git a/src/ipc-freebsd.h b/src/ipc-freebsd.h index 1acddc4..206ebcd 100644 --- a/src/ipc-freebsd.h +++ b/src/ipc-freebsd.h @@ -91,68 +91,163 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) dev->flags |= WGDEVICE_HAS_LISTEN_PORT; } } - if (nvlist_exists_number(nvl_device, "jc")) { + if (nvlist_exists_number(nvl_device, "jc")) { number = nvlist_get_number(nvl_device, "jc"); if (number <= UINT16_MAX){ dev->junk_packet_count = number; dev->flags |= WGDEVICE_HAS_JC; } } - if (nvlist_exists_number(nvl_device, "jmin")) { + if (nvlist_exists_number(nvl_device, "jmin")) { number = nvlist_get_number(nvl_device, "jmin"); if (number <= UINT16_MAX){ - dev->junk_packet_min_size = number; + dev->junk_packet_min_size = number; dev->flags |= WGDEVICE_HAS_JMIN; - } + } } - if (nvlist_exists_number(nvl_device, "jmax")) { + if (nvlist_exists_number(nvl_device, "jmax")) { number = nvlist_get_number(nvl_device, "jmax"); if (number <= UINT16_MAX){ - dev->junk_packet_max_size = number; + dev->junk_packet_max_size = number; dev->flags |= WGDEVICE_HAS_JMAX; - } + } } - if (nvlist_exists_number(nvl_device, "s1")) { + if (nvlist_exists_number(nvl_device, "s1")) { number = nvlist_get_number(nvl_device, "s1"); if (number <= UINT16_MAX){ - dev->init_packet_junk_size = number; + dev->init_packet_junk_size = number; dev->flags |= WGDEVICE_HAS_S1; - } + } } - if (nvlist_exists_number(nvl_device, "s2")) { + if (nvlist_exists_number(nvl_device, "s2")) { number = nvlist_get_number(nvl_device, "s2"); if (number <= UINT16_MAX){ - dev->response_packet_junk_size = number; + dev->response_packet_junk_size = number; dev->flags |= WGDEVICE_HAS_S2; - } + } } - if (nvlist_exists_number(nvl_device, "h1")) { + if (nvlist_exists_number(nvl_device, "s3")) { + number = nvlist_get_number(nvl_device, "s3"); + if (number <= UINT16_MAX){ + dev->cookie_reply_packet_junk_size = number; + dev->flags |= WGDEVICE_HAS_S3; + } + } + if (nvlist_exists_number(nvl_device, "s4")) { + number = nvlist_get_number(nvl_device, "s4"); + if (number <= UINT16_MAX){ + dev->transport_packet_junk_size = number; + dev->flags |= WGDEVICE_HAS_S4; + } + } + if (nvlist_exists_number(nvl_device, "h1")) { number = nvlist_get_number(nvl_device, "h1"); if (number <= UINT32_MAX){ - dev->init_packet_magic_header = number; + dev->init_packet_magic_header = number; dev->flags |= WGDEVICE_HAS_H1; - } + } } - if (nvlist_exists_number(nvl_device, "h2")) { + if (nvlist_exists_number(nvl_device, "h2")) { number = nvlist_get_number(nvl_device, "h2"); if (number <= UINT32_MAX){ - dev->response_packet_magic_header = number; + dev->response_packet_magic_header = number; dev->flags |= WGDEVICE_HAS_H2; - } + } } - if (nvlist_exists_number(nvl_device, "h3")) { + if (nvlist_exists_number(nvl_device, "h3")) { number = nvlist_get_number(nvl_device, "h3"); if (number <= UINT32_MAX){ - dev->underload_packet_magic_header = number; + dev->underload_packet_magic_header = number; dev->flags |= WGDEVICE_HAS_H3; - } + } } - if (nvlist_exists_number(nvl_device, "h4")) { + if (nvlist_exists_number(nvl_device, "h4")) { number = nvlist_get_number(nvl_device, "h4"); if (number <= UINT32_MAX){ - dev->transport_packet_magic_header = number; + dev->transport_packet_magic_header = number; dev->flags |= WGDEVICE_HAS_H4; - } + } + } + if (nvlist_exists_binary(nvl_device, "i1")) + { + binary = nvlist_get_binary(nvl_device, "i1", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->i1 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_I1; + } + } + if (nvlist_exists_binary(nvl_device, "i2")) + { + binary = nvlist_get_binary(nvl_device, "i2", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->i2 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_I2; + } + } + if (nvlist_exists_binary(nvl_device, "i3")) + { + binary = nvlist_get_binary(nvl_device, "i3", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->i3 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_I3; + } + } + if (nvlist_exists_binary(nvl_device, "i4")) + { + binary = nvlist_get_binary(nvl_device, "i4", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->i4 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_I4; + } + } + if (nvlist_exists_binary(nvl_device, "i5")) + { + binary = nvlist_get_binary(nvl_device, "i5", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->i5 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_I5; + } + } + if (nvlist_exists_binary(nvl_device, "j1")) + { + binary = nvlist_get_binary(nvl_device, "j1", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->j1 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_J1; + } + } + if (nvlist_exists_binary(nvl_device, "j2")) + { + binary = nvlist_get_binary(nvl_device, "j2", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->j2 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_J2; + } + } + if (nvlist_exists_binary(nvl_device, "j3")) + { + binary = nvlist_get_binary(nvl_device, "j3", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->j3 = strdup((const char*)binary); + dev->flags |= WGDEVICE_HAS_J3; + } + } + if (nvlist_exists_binary(nvl_device, "itime")) + { + number = nvlist_get_number(nvl_device, "itime"); + if (number <= UINT32_MAX) + { + dev->itime = number; + dev->flags |= WGDEVICE_HAS_ITIME; + } } if (nvlist_exists_number(nvl_device, "user-cookie")) { @@ -346,6 +441,10 @@ static int kernel_set_device(struct wgdevice *dev) nvlist_add_number(nvl_device, "s1", dev->init_packet_junk_size); if (dev->flags & WGDEVICE_HAS_S2) nvlist_add_number(nvl_device, "s2", dev->response_packet_junk_size); + if (dev->flags & WGDEVICE_HAS_S3) + nvlist_add_number(nvl_device, "s3", dev->cookie_reply_packet_junk_size); + if (dev->flags & WGDEVICE_HAS_S4) + nvlist_add_number(nvl_device, "s4", dev->transport_packet_junk_size); if (dev->flags & WGDEVICE_HAS_H1) nvlist_add_number(nvl_device, "h1", dev->init_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H2) @@ -354,6 +453,24 @@ static int kernel_set_device(struct wgdevice *dev) nvlist_add_number(nvl_device, "h3", dev->underload_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H4) nvlist_add_number(nvl_device, "h4", dev->transport_packet_magic_header); + if (dev->flags & WGDEVICE_HAS_I1) + nvlist_add_binary(nvl_device, "i1", dev->i1, strlen(dev->i1) + 1); + if (dev->flags & WGDEVICE_HAS_I2) + nvlist_add_binary(nvl_device, "i2", dev->i2, strlen(dev->i2) + 1); + if (dev->flags & WGDEVICE_HAS_I3) + nvlist_add_binary(nvl_device, "i3", dev->i3, strlen(dev->i3) + 1); + if (dev->flags & WGDEVICE_HAS_I4) + nvlist_add_binary(nvl_device, "i4", dev->i4, strlen(dev->i4) + 1); + if (dev->flags & WGDEVICE_HAS_I5) + nvlist_add_binary(nvl_device, "i5", dev->i5, strlen(dev->i5) + 1); + if (dev->flags & WGDEVICE_HAS_J1) + nvlist_add_binary(nvl_device, "j1", dev->j1, strlen(dev->j1) + 1); + if (dev->flags & WGDEVICE_HAS_J2) + nvlist_add_binary(nvl_device, "j2", dev->j2, strlen(dev->j2) + 1); + if (dev->flags & WGDEVICE_HAS_J3) + nvlist_add_binary(nvl_device, "j3", dev->j3, strlen(dev->j3) + 1); + if (dev->flags & WGDEVICE_HAS_ITIME) + nvlist_add_number(nvl_device, "itime", dev->itime); if (dev->flags & WGDEVICE_HAS_FWMARK) nvlist_add_number(nvl_device, "user-cookie", dev->fwmark); if (dev->flags & WGDEVICE_REPLACE_PEERS) diff --git a/src/ipc-linux.h b/src/ipc-linux.h index c6d9847..0531ff5 100644 --- a/src/ipc-linux.h +++ b/src/ipc-linux.h @@ -173,6 +173,10 @@ again: mnl_attr_put_u16(nlh, WGDEVICE_A_S1, dev->init_packet_junk_size); if (dev->flags & WGDEVICE_HAS_S2) mnl_attr_put_u16(nlh, WGDEVICE_A_S2, dev->response_packet_junk_size); + if (dev->flags & WGDEVICE_HAS_S3) + mnl_attr_put_u16(nlh, WGDEVICE_A_S3, dev->cookie_reply_packet_junk_size); + if (dev->flags & WGDEVICE_HAS_S4) + mnl_attr_put_u16(nlh, WGDEVICE_A_S4, dev->transport_packet_junk_size); if (dev->flags & WGDEVICE_HAS_H1) mnl_attr_put_u32(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H2) @@ -181,6 +185,24 @@ again: mnl_attr_put_u32(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H4) mnl_attr_put_u32(nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header); + if (dev->flags & WGDEVICE_HAS_I1) + mnl_attr_put_strz(nlh, WGDEVICE_A_I1, dev->i1); + if (dev->flags & WGDEVICE_HAS_I2) + mnl_attr_put_strz(nlh, WGDEVICE_A_I2, dev->i2); + if (dev->flags & WGDEVICE_HAS_I3) + mnl_attr_put_strz(nlh, WGDEVICE_A_I3, dev->i3); + if (dev->flags & WGDEVICE_HAS_I4) + mnl_attr_put_strz(nlh, WGDEVICE_A_I4, dev->i4); + if (dev->flags & WGDEVICE_HAS_I5) + mnl_attr_put_strz(nlh, WGDEVICE_A_I5, dev->i5); + if (dev->flags & WGDEVICE_HAS_J1) + mnl_attr_put_strz(nlh, WGDEVICE_A_J1, dev->j1); + if (dev->flags & WGDEVICE_HAS_J2) + mnl_attr_put_strz(nlh, WGDEVICE_A_J2, dev->j2); + if (dev->flags & WGDEVICE_HAS_J3) + mnl_attr_put_strz(nlh, WGDEVICE_A_J3, dev->j3); + if (dev->flags & WGDEVICE_HAS_ITIME) + mnl_attr_put_u32(nlh, WGDEVICE_A_ITIME, dev->itime); if (dev->flags & WGDEVICE_HAS_FWMARK) mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark); if (dev->flags & WGDEVICE_REPLACE_PEERS) @@ -226,6 +248,13 @@ again: mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_ADVANCED_SECURITY, 0, NULL); flags |= WGPEER_F_HAS_ADVANCED_SECURITY; } + if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE) + { + if (peer->special_handshake) + mnl_attr_put_check( + nlh, SOCKET_BUFFER_SIZE, WGPEER_A_SPECIAL_HANDSHAKE, 0, NULL); + flags |= WGPEER_F_HAS_SPECIAL_HANDSHAKE; + } if (flags) { if (!mnl_attr_put_u32_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_FLAGS, flags)) goto toobig_peers; @@ -402,6 +431,13 @@ static int parse_peer(const struct nlattr *attr, void *data) peer->flags |= WGPEER_HAS_ADVANCED_SECURITY; peer->advanced_security = false; } + if ( + flags & WGPEER_F_HAS_SPECIAL_HANDSHAKE && + !(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)) + { + peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; + peer->special_handshake = false; + } } break; case WGPEER_A_ADVANCED_SECURITY: @@ -413,6 +449,17 @@ static int parse_peer(const struct nlattr *attr, void *data) } } break; + case WGPEER_A_SPECIAL_HANDSHAKE: + if (!mnl_attr_validate(attr, MNL_TYPE_FLAG)) + { + peer->special_handshake = true; + + if (!(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)) + { + peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; + } + } + break; case WGPEER_A_ALLOWEDIPS: return mnl_attr_parse_nested(attr, parse_allowedips, peer); } @@ -513,6 +560,18 @@ static int parse_device(const struct nlattr *attr, void *data) device->flags |= WGDEVICE_HAS_S2; } break; + case WGDEVICE_A_S3: + if (!mnl_attr_validate(attr, MNL_TYPE_U16)) { + device->cookie_reply_packet_junk_size = mnl_attr_get_u16(attr); + device->flags |= WGDEVICE_HAS_S3; + } + break; + case WGDEVICE_A_S4: + if (!mnl_attr_validate(attr, MNL_TYPE_U16)) { + device->transport_packet_junk_size = mnl_attr_get_u16(attr); + device->flags |= WGDEVICE_HAS_S4; + } + break; case WGDEVICE_A_H1: if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { device->init_packet_magic_header = mnl_attr_get_u32(attr); @@ -537,6 +596,69 @@ static int parse_device(const struct nlattr *attr, void *data) device->flags |= WGDEVICE_HAS_H4; } break; + case WGDEVICE_A_I1: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->i1 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_I1; + } + break; + case WGDEVICE_A_I2: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->i2 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_I2; + } + break; + case WGDEVICE_A_I3: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->i3 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_I3; + } + break; + case WGDEVICE_A_I4: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->i4 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_I4; + } + break; + case WGDEVICE_A_I5: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->i5 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_I5; + } + break; + case WGDEVICE_A_J1: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->j1 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_J1; + } + break; + case WGDEVICE_A_J2: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->j2 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_J2; + } + break; + case WGDEVICE_A_J3: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->j3 = strdup(mnl_attr_get_str(attr)); + device->flags |= WGDEVICE_HAS_J3; + } + break; + case WGDEVICE_A_ITIME: + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + { + device->itime = mnl_attr_get_u32(attr); + device->flags |= WGDEVICE_HAS_ITIME; + } + break; } return MNL_CB_OK; diff --git a/src/ipc-openbsd.h b/src/ipc-openbsd.h index 1b0955d..dd063ae 100644 --- a/src/ipc-openbsd.h +++ b/src/ipc-openbsd.h @@ -135,6 +135,16 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) dev->flags |= WGDEVICE_HAS_S2; } + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_S3) { + dev->cookie_reply_packet_junk_size = wg_iface->i_cookie_reply_packet_junk_size; + dev->flags |= WGDEVICE_HAS_S3; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_S4) { + dev->transport_packet_junk_size = wg_iface->i_transport_packet_junk_size; + dev->flags |= WGDEVICE_HAS_S4; + } + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H1) { dev->init_packet_magic_header = wg_iface->i_init_packet_magic_header; dev->flags |= WGDEVICE_HAS_H1; @@ -154,7 +164,61 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) dev->transport_packet_magic_header = wg_iface->i_transport_packet_magic_header; dev->flags |= WGDEVICE_HAS_H4; } - + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I1) + { + dev->i1 = strdup(wg_iface->i_i1); + dev->flags |= WGDEVICE_HAS_I1; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I2) + { + dev->i2 = strdup(wg_iface->i_i2); + dev->flags |= WGDEVICE_HAS_I2; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I3) + { + dev->i3 = strdup(wg_iface->i_i3); + dev->flags |= WGDEVICE_HAS_I3; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I4) + { + dev->i4 = strdup(wg_iface->i_i4); + dev->flags |= WGDEVICE_HAS_I4; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I5) + { + dev->i5 = strdup(wg_iface->i_i5); + dev->flags |= WGDEVICE_HAS_I5; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J1) + { + dev->j1 = strdup(wg_iface->i_j1); + dev->flags |= WGDEVICE_HAS_J1; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J2) + { + dev->j2 = strdup(wg_iface->i_j2); + dev->flags |= WGDEVICE_HAS_J2; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J3) + { + dev->j3 = strdup(wg_iface->i_j3); + dev->flags |= WGDEVICE_HAS_J3; + } + + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_ITIME) + { + dev->itime = wg_iface->i_itime ; + dev->flags |= WGDEVICE_HAS_ITIME; + } + wg_peer = &wg_iface->i_peers[0]; for (size_t i = 0; i < wg_iface->i_peers_count; ++i) { peer = calloc(1, sizeof(*peer)); @@ -292,6 +356,16 @@ static int kernel_set_device(struct wgdevice *dev) wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S2; } + if (dev->flags & WGDEVICE_HAS_S3) { + wg_iface->i_cookie_reply_packet_junk_size = dev->cookie_reply_packet_junk_size; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S3; + } + + if (dev->flags & WGDEVICE_HAS_S4) { + wg_iface->i_transport_packet_junk_size = dev->transport_packet_junk_size; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_S4; + } + if (dev->flags & WGDEVICE_HAS_H1) { wg_iface->i_init_packet_magic_header = dev->init_packet_magic_header; wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H1; @@ -312,6 +386,60 @@ static int kernel_set_device(struct wgdevice *dev) wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H4; } + if (dev->flags & WGDEVICE_HAS_I1) + { + wg_iface->i_i1 = strdup(dev->i1); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I1; + } + + if (dev->flags & WGDEVICE_HAS_I2) + { + wg_iface->i_i2 = strdup(dev->i2); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I2; + } + + if (dev->flags & WGDEVICE_HAS_I3) + { + wg_iface->i_i3 = strdup(dev->i3); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I3; + } + + if (dev->flags & WGDEVICE_HAS_I4) + { + wg_iface->i_i4 = strdup(dev->i4); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I4; + } + + if (dev->flags & WGDEVICE_HAS_I5) + { + wg_iface->i_i5 = strdup(dev->i5); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I5; + } + + if (dev->flags & WGDEVICE_HAS_J1) + { + wg_iface->i_j1 = strdup(dev->j1); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J1; + } + + if (dev->flags & WGDEVICE_HAS_J2) + { + wg_iface->i_j2 = strdup(dev->j2); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J2; + } + + if (dev->flags & WGDEVICE_HAS_J3) + { + wg_iface->i_j3 = strdup(dev->j3); + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J3; + } + + if (dev->flags & WGDEVICE_HAS_ITIME) + { + wg_iface->i_itime = dev->itime; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_ITIME; + } + peer_count = 0; wg_peer = &wg_iface->i_peers[0]; for_each_wgpeer(dev, peer) { diff --git a/src/ipc-uapi.h b/src/ipc-uapi.h index 250606c..32be0d8 100644 --- a/src/ipc-uapi.h +++ b/src/ipc-uapi.h @@ -61,6 +61,10 @@ static int userspace_set_device(struct wgdevice *dev) fprintf(f, "s1=%u\n", dev->init_packet_junk_size); if (dev->flags & WGDEVICE_HAS_S2) fprintf(f, "s2=%u\n", dev->response_packet_junk_size); + if (dev->flags & WGDEVICE_HAS_S3) + fprintf(f, "s3=%u\n", dev->cookie_reply_packet_junk_size); + if (dev->flags & WGDEVICE_HAS_S4) + fprintf(f, "s4=%u\n", dev->transport_packet_junk_size); if (dev->flags & WGDEVICE_HAS_H1) fprintf(f, "h1=%u\n", dev->init_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H2) @@ -70,6 +74,25 @@ static int userspace_set_device(struct wgdevice *dev) if (dev->flags & WGDEVICE_HAS_H4) fprintf(f, "h4=%u\n", dev->transport_packet_magic_header); + if (dev->flags & WGDEVICE_HAS_I1) + fprintf(f, "i1=%s\n", dev->i1); + if (dev->flags & WGDEVICE_HAS_I2) + fprintf(f, "i2=%s\n", dev->i2); + if (dev->flags & WGDEVICE_HAS_I3) + fprintf(f, "i3=%s\n", dev->i3); + if (dev->flags & WGDEVICE_HAS_I4) + fprintf(f, "i4=%s\n", dev->i4); + if (dev->flags & WGDEVICE_HAS_I5) + fprintf(f, "i5=%s\n", dev->i5); + if (dev->flags & WGDEVICE_HAS_J1) + fprintf(f, "j1=%s\n", dev->j1); + if (dev->flags & WGDEVICE_HAS_J2) + fprintf(f, "j2=%s\n", dev->j2); + if (dev->flags & WGDEVICE_HAS_J3) + fprintf(f, "j3=%s\n", dev->j3); + if (dev->flags & WGDEVICE_HAS_ITIME) + fprintf(f, "itime=%u\n", dev->itime); + for_each_wgpeer(dev, peer) { key_to_hex(hex, peer->public_key); fprintf(f, "public_key=%s\n", hex); @@ -77,6 +100,11 @@ static int userspace_set_device(struct wgdevice *dev) ret = -EINVAL; goto out; } + if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE) + { + ret = -EINVAL; + goto out; + } if (peer->flags & WGPEER_REMOVE_ME) { fprintf(f, "remove=true\n"); continue; @@ -220,6 +248,12 @@ static int userspace_get_device(struct wgdevice **out, const char *iface) } else if(!peer && !strcmp(key, "s2")) { dev->response_packet_junk_size = NUM(0xffffU); dev->flags |= WGDEVICE_HAS_S2; + } else if(!peer && !strcmp(key, "s3")) { + dev->cookie_reply_packet_junk_size = NUM(0xffffU); + dev->flags |= WGDEVICE_HAS_S3; + } else if(!peer && !strcmp(key, "s4")) { + dev->transport_packet_junk_size = NUM(0xffffU); + dev->flags |= WGDEVICE_HAS_S4; } else if(!peer && !strcmp(key, "h1")) { dev->init_packet_magic_header = NUM(0xffffffffU); dev->flags |= WGDEVICE_HAS_H1; @@ -232,6 +266,41 @@ static int userspace_get_device(struct wgdevice **out, const char *iface) } else if(!peer && !strcmp(key, "h4")) { dev->transport_packet_magic_header = NUM(0xffffffffU); dev->flags |= WGDEVICE_HAS_H4; + } else if (!peer && !strcmp(key, "i1")) { + dev->i1 = strdup(value); + dev->flags |= WGDEVICE_HAS_I1; + } + else if (!peer && !strcmp(key, "i2")) { + dev->i2 = strdup(value); + dev->flags |= WGDEVICE_HAS_I2; + } + else if (!peer && !strcmp(key, "i3")) { + dev->i3 = strdup(value); + dev->flags |= WGDEVICE_HAS_I3; + } + else if (!peer && !strcmp(key, "i4")) { + dev->i4 = strdup(value); + dev->flags |= WGDEVICE_HAS_I4; + } + else if (!peer && !strcmp(key, "i5")) { + dev->i5 = strdup(value); + dev->flags |= WGDEVICE_HAS_I5; + } + else if (!peer && !strcmp(key, "j1")) { + dev->j1 = strdup(value); + dev->flags |= WGDEVICE_HAS_J1; + } + else if (!peer && !strcmp(key, "j2")) { + dev->j2 = strdup(value); + dev->flags |= WGDEVICE_HAS_J2; + } + else if (!peer && !strcmp(key, "j3")) { + dev->j3 = strdup(value); + dev->flags |= WGDEVICE_HAS_J3; + } + else if (!peer && !strcmp(key, "itime")) { + dev->itime = NUM(0xffffffffU); + dev->flags |= WGDEVICE_HAS_ITIME; } else if (!strcmp(key, "public_key")) { struct wgpeer *new_peer = calloc(1, sizeof(*new_peer)); diff --git a/src/ipc-windows.h b/src/ipc-windows.h index 7925cf0..faa8b8f 100644 --- a/src/ipc-windows.h +++ b/src/ipc-windows.h @@ -283,6 +283,14 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) dev->response_packet_junk_size = wg_iface->ResponsePacketJunkSize; dev->flags |= WGDEVICE_HAS_S2; } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_S3) { + dev->cookie_reply_packet_junk_size = wg_iface->CookieReplyPacketJunkSize; + dev->flags |= WGDEVICE_HAS_S3; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_S4) { + dev->transport_packet_junk_size = wg_iface->TransportPacketJunkSize; + dev->flags |= WGDEVICE_HAS_S4; + } if (wg_iface->Flags & WG_IOCTL_INTERFACE_H1) { dev->init_packet_magic_header = wg_iface->InitPacketMagicHeader; dev->flags |= WGDEVICE_HAS_H1; @@ -299,6 +307,67 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) dev->transport_packet_magic_header = wg_iface->TransportPacketMagicHeader; dev->flags |= WGDEVICE_HAS_H4; } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I1) + { + const size_t i1_size = strlen((char*)wg_iface->I1) + 1; + dev->i1 = (char*)malloc(i1_size); + memcpy(dev->i1, wg_iface->I1, i1_size); + dev->flags |= WGDEVICE_HAS_I1; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I2) + { + const size_t i2_size = strlen((char*)wg_iface->I2) + 1; + dev->i2 = (char*)malloc(i2_size); + memcpy(dev->i2, wg_iface->I2, i2_size); + dev->flags |= WGDEVICE_HAS_I2; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I3) + { + const size_t i3_size = strlen((char*)wg_iface->I3) + 1; + dev->i3 = (char*)malloc(i3_size); + memcpy(dev->i3, wg_iface->I3, i3_size); + dev->flags |= WGDEVICE_HAS_I3; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I4) + { + const size_t i4_size = strlen((char*)wg_iface->I4) + 1; + dev->i4 = (char*)malloc(i4_size); + memcpy(dev->i4, wg_iface->I4, i4_size); + dev->flags |= WGDEVICE_HAS_I4; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I5) + { + const size_t i5_size = strlen((char*)wg_iface->I5) + 1; + dev->i5 = (char*)malloc(i5_size); + memcpy(dev->i5, wg_iface->I5, i5_size); + dev->flags |= WGDEVICE_HAS_I5; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_J1) + { + const size_t j1_size = strlen((char*)wg_iface->J1) + 1; + dev->j1 = (char*)malloc(j1_size); + memcpy(dev->j1, wg_iface->J1, j1_size); + dev->flags |= WGDEVICE_HAS_J1; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_J2) + { + const size_t j2_size = strlen((char*)wg_iface->J2) + 1; + dev->j2 = (char*)malloc(j2_size); + memcpy(dev->j2, wg_iface->J2, j2_size); + dev->flags |= WGDEVICE_HAS_J2; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_J3) + { + const size_t j3_size = strlen((char*)wg_iface->J3) + 1; + dev->j3 = (char*)malloc(j3_size); + memcpy(dev->j3, wg_iface->J3, j3_size); + dev->flags |= WGDEVICE_HAS_J3; + } + if (wg_iface->Flags & WG_IOCTL_INTERFACE_ITIME) + { + dev->itime = wg_iface->Itime; + dev->flags |= WGDEVICE_HAS_ITIME; + } wg_peer = buf + sizeof(WG_IOCTL_INTERFACE); for (ULONG i = 0; i < wg_iface->PeersCount; ++i) { @@ -446,6 +515,14 @@ static int kernel_set_device(struct wgdevice *dev) wg_iface->ResponsePacketJunkSize = dev->response_packet_junk_size; wg_iface->Flags |= WG_IOCTL_INTERFACE_S2; } + if (dev->flags & WGDEVICE_HAS_S3) { + wg_iface->CookieReplyPacketJunkSize = dev->cookie_reply_packet_junk_size; + wg_iface->Flags |= WG_IOCTL_INTERFACE_S3; + } + if (dev->flags & WGDEVICE_HAS_S4) { + wg_iface->TransportPacketJunkSize = dev->transport_packet_junk_size; + wg_iface->Flags |= WG_IOCTL_INTERFACE_S4; + } if (dev->flags & WGDEVICE_HAS_H1) { wg_iface->InitPacketMagicHeader = dev->init_packet_magic_header; @@ -467,6 +544,68 @@ static int kernel_set_device(struct wgdevice *dev) wg_iface->Flags |= WG_IOCTL_INTERFACE_H4; } + if (dev->flags & WGDEVICE_HAS_I1) + { + const size_t i1_size = strlen(dev->i1) + 1; + wg_iface->I1 = (UCHAR*)malloc(i1_size); + memcpy(wg_iface->I1, dev->i1, i1_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_I1; + } + if (dev->flags & WGDEVICE_HAS_I2) + { + const size_t i2_size = strlen(dev->i2) + 1; + wg_iface->I2 = (UCHAR*)malloc(i2_size); + memcpy(wg_iface->I2, dev->i2, i2_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_I2; + } + if (dev->flags & WGDEVICE_HAS_I3) + { + const size_t i3_size = strlen(dev->i3) + 1; + wg_iface->I3 = (UCHAR*)malloc(i3_size); + memcpy(wg_iface->I3, dev->i3, i3_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_I3; + } + if (dev->flags & WGDEVICE_HAS_I4) + { + const size_t i4_size = strlen(dev->i4) + 1; + wg_iface->I4 = (UCHAR*)malloc(i4_size); + memcpy(wg_iface->I4, dev->i4, i4_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_I4; + } + if (dev->flags & WGDEVICE_HAS_I5) + { + const size_t i5_size = strlen(dev->i5) + 1; + wg_iface->I5 = (UCHAR*)malloc(i5_size); + memcpy(wg_iface->I5, dev->i5, i5_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_I5; + } + if (dev->flags & WGDEVICE_HAS_J1) + { + const size_t j1_size = strlen(dev->j1) + 1; + wg_iface->J1 = (UCHAR*)malloc(j1_size); + memcpy(wg_iface->J1, dev->j1, j1_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_J1; + } + if (dev->flags & WGDEVICE_HAS_J2) + { + const size_t j2_size = strlen(dev->j2) + 1; + wg_iface->J2 = (UCHAR*)malloc(j2_size); + memcpy(wg_iface->J2, dev->j2, j2_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_J2; + } + if (dev->flags & WGDEVICE_HAS_J3) + { + const size_t j3_size = strlen(dev->j3) + 1; + wg_iface->J3 = (UCHAR*)malloc(j3_size); + memcpy(wg_iface->J3, dev->j3, j3_size); + wg_iface->Flags |= WG_IOCTL_INTERFACE_J3; + } + if (dev->flags & WGDEVICE_HAS_ITIME) + { + wg_iface->Itime = dev->itime; + wg_iface->Flags |= WG_IOCTL_INTERFACE_ITIME; + } + peer_count = 0; wg_peer = (void *)wg_iface + sizeof(WG_IOCTL_INTERFACE); for_each_wgpeer(dev, peer) { diff --git a/src/set.c b/src/set.c index 8f749b1..6bec30a 100644 --- a/src/set.c +++ b/src/set.c @@ -18,7 +18,7 @@ int set_main(int argc, const char *argv[]) int ret = 1; if (argc < 3) { - fprintf(stderr, "Usage: %s %s [listen-port ] [fwmark ] [private-key ] [peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips /[,/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); + fprintf(stderr, "Usage: %s %s [listen-port ] [fwmark ] [private-key ] [jc ] [jmin ] [jmax ] [s1 ] [s2 ] [h1 ] [h2 ] [h3 ] [h4 ] [i1 \"\"] [i2 \"\"] [i3 \"\"] [i4 \"\"] [i5 \"\"] [j1 \"\"] [j2 \"\"] [j3 \"\"] [itime ][peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips /[,/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); return 1; } diff --git a/src/show.c b/src/show.c index 001ca1d..9b047c9 100644 --- a/src/show.c +++ b/src/show.c @@ -202,7 +202,7 @@ static char *bytes(uint64_t b) static const char *COMMAND_NAME; static void show_usage(void) { - fprintf(stderr, "Usage: %s %s { | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump]\n", PROG_NAME, COMMAND_NAME); + fprintf(stderr, "Usage: %s %s { | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump | jc | jmin | jmax | s1 | s2 | h1 | h2 | h3 | h4 | i1 | i2 | i3 | i4 | i5 | j1 | j2 | j3 | itime]\n", PROG_NAME, COMMAND_NAME); } static void pretty_print(struct wgdevice *device) @@ -230,6 +230,10 @@ static void pretty_print(struct wgdevice *device) terminal_printf(" " TERMINAL_BOLD "s1" TERMINAL_RESET ": %u\n", device->init_packet_junk_size); if (device->response_packet_junk_size) terminal_printf(" " TERMINAL_BOLD "s2" TERMINAL_RESET ": %u\n", device->response_packet_junk_size); + if (device->cookie_reply_packet_junk_size) + terminal_printf(" " TERMINAL_BOLD "s3" TERMINAL_RESET ": %u\n", device->cookie_reply_packet_junk_size); + if (device->transport_packet_junk_size) + terminal_printf(" " TERMINAL_BOLD "s4" TERMINAL_RESET ": %u\n", device->transport_packet_junk_size); if (device->init_packet_magic_header) terminal_printf(" " TERMINAL_BOLD "h1" TERMINAL_RESET ": %u\n", device->init_packet_magic_header); if (device->response_packet_magic_header) @@ -238,6 +242,25 @@ static void pretty_print(struct wgdevice *device) terminal_printf(" " TERMINAL_BOLD "h3" TERMINAL_RESET ": %u\n", device->underload_packet_magic_header); if (device->transport_packet_magic_header) terminal_printf(" " TERMINAL_BOLD "h4" TERMINAL_RESET ": %u\n", device->transport_packet_magic_header); + if (device->i1) + terminal_printf(" " TERMINAL_BOLD "i1" TERMINAL_RESET ": %s\n", device->i1); + if (device->i2) + terminal_printf(" " TERMINAL_BOLD "i2" TERMINAL_RESET ": %s\n", device->i2); + if (device->i3) + terminal_printf(" " TERMINAL_BOLD "i3" TERMINAL_RESET ": %s\n", device->i3); + if (device->i4) + terminal_printf(" " TERMINAL_BOLD "i4" TERMINAL_RESET ": %s\n", device->i4); + if (device->i5) + terminal_printf(" " TERMINAL_BOLD "i5" TERMINAL_RESET ": %s\n", device->i5); + if (device->j1) + terminal_printf(" " TERMINAL_BOLD "j1" TERMINAL_RESET ": %s\n", device->j1); + if (device->j2) + terminal_printf(" " TERMINAL_BOLD "j2" TERMINAL_RESET ": %s\n", device->j2); + if (device->j3) + terminal_printf(" " TERMINAL_BOLD "j3" TERMINAL_RESET ": %s\n", device->j3); + if (device->itime) + terminal_printf(" " TERMINAL_BOLD "itime" TERMINAL_RESET ": %u\n", device->itime); + if (device->first_peer) { sort_peers(device); terminal_printf("\n"); @@ -287,6 +310,16 @@ static void dump_print(struct wgdevice *device, bool with_interface) printf("%u\t", device->response_packet_magic_header); printf("%u\t", device->underload_packet_magic_header); printf("%u\t", device->transport_packet_magic_header); + printf("%s\t", device->i1); + printf("%s\t", device->i2); + printf("%s\t", device->i3); + printf("%s\t", device->i4); + printf("%s\t", device->i5); + printf("%s\t", device->j1); + printf("%s\t", device->j2); + printf("%s\t", device->j3); + printf("%u\t", device->itime); + if (device->fwmark) printf("0x%x\n", device->fwmark); else @@ -374,6 +407,42 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int if (with_interface) printf("%s\t", device->name); printf("%u\n", device->transport_packet_magic_header); + } else if(!strcmp(param, "i1")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->i1); + } else if(!strcmp(param, "i2")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->i2); + } else if(!strcmp(param, "i3")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->i3); + } else if(!strcmp(param, "i4")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->i4); + } else if(!strcmp(param, "i5")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->i5); + } else if(!strcmp(param, "j1")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->j1); + } else if(!strcmp(param, "j2")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->j2); + } else if(!strcmp(param, "j3")) { + if (with_interface) + printf("%s\t", device->name); + printf("%s\n", device->j3); + } else if(!strcmp(param, "itime")) { + if (with_interface) + printf("%s\t", device->name); + printf("%u\n", device->itime); } else if (!strcmp(param, "endpoints")) { for_each_wgpeer(device, peer) { if (with_interface) diff --git a/src/showconf.c b/src/showconf.c index 424b2be..b049f6e 100644 --- a/src/showconf.c +++ b/src/showconf.c @@ -56,6 +56,10 @@ int showconf_main(int argc, const char *argv[]) printf("S1 = %u\n", device->init_packet_junk_size); if (device->flags & WGDEVICE_HAS_S2) printf("S2 = %u\n", device->response_packet_junk_size); + if (device->flags & WGDEVICE_HAS_S3) + printf("S3 = %u\n", device->cookie_reply_packet_junk_size); + if (device->flags & WGDEVICE_HAS_S4) + printf("S4 = %u\n", device->transport_packet_junk_size); if (device->flags & WGDEVICE_HAS_H1) printf("H1 = %u\n", device->init_packet_magic_header); if (device->flags & WGDEVICE_HAS_H2) @@ -64,6 +68,24 @@ int showconf_main(int argc, const char *argv[]) printf("H3 = %u\n", device->underload_packet_magic_header); if (device->flags & WGDEVICE_HAS_H4) printf("H4 = %u\n", device->transport_packet_magic_header); + if (device->flags & WGDEVICE_HAS_I1) + printf("I1 = %s\n", device->i1); + if (device->flags & WGDEVICE_HAS_I2) + printf("I2 = %s\n", device->i2); + if (device->flags & WGDEVICE_HAS_I3) + printf("I3 = %s\n", device->i3); + if (device->flags & WGDEVICE_HAS_I4) + printf("I4 = %s\n", device->i4); + if (device->flags & WGDEVICE_HAS_I5) + printf("I5 = %s\n", device->i5); + if (device->flags & WGDEVICE_HAS_J1) + printf("J1 = %s\n", device->j1); + if (device->flags & WGDEVICE_HAS_J2) + printf("J2 = %s\n", device->j2); + if (device->flags & WGDEVICE_HAS_J3) + printf("J3 = %s\n", device->j3); + if (device->flags & WGDEVICE_HAS_ITIME) + printf("Itime = %u\n", device->itime); printf("\n"); for_each_wgpeer(device, peer) { @@ -76,6 +98,9 @@ int showconf_main(int argc, const char *argv[]) if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) { printf("AdvancedSecurity = %s\n", peer->advanced_security ? "on" : "off"); } + if (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE) { + printf("SpecialHandshake = %s\n", peer->special_handshake ? "on" : "off"); + } if (peer->first_allowedip) printf("AllowedIPs = "); for_each_wgallowedip(peer, allowedip) { diff --git a/src/uapi/linux/linux/wireguard.h b/src/uapi/linux/linux/wireguard.h index 8d38c90..4438e83 100644 --- a/src/uapi/linux/linux/wireguard.h +++ b/src/uapi/linux/linux/wireguard.h @@ -114,6 +114,9 @@ * WGPEER_A_ADVANCED_SECURITY: flag indicating that advanced security * techniques provided by AmneziaWG should * be used. + * WGPEER_A_SPECIAL_HANDSHAKE: flag indicating that special handshake + * techniques provided by AmneziaWG should + * be used. * 0: NLA_NESTED * ... * ... @@ -147,6 +150,9 @@ * WGPEER_A_ADVANCED_SECURITY: flag indicating that advanced security * techniques provided by AmneziaWG should * be used. + * WGPEER_A_SPECIAL_HANDSHAKE: flag indicating that special handshake + * techniques provided by AmneziaWG should + * be used. * */ @@ -187,10 +193,21 @@ enum wgdevice_attribute { WGDEVICE_A_JMAX, WGDEVICE_A_S1, WGDEVICE_A_S2, + WGDEVICE_A_S3, + WGDEVICE_A_S4, WGDEVICE_A_H1, WGDEVICE_A_H2, WGDEVICE_A_H3, WGDEVICE_A_H4, + WGDEVICE_A_I1, + WGDEVICE_A_I2, + WGDEVICE_A_I3, + WGDEVICE_A_I4, + WGDEVICE_A_I5, + WGDEVICE_A_J1, + WGDEVICE_A_J2, + WGDEVICE_A_J3, + WGDEVICE_A_ITIME, WGDEVICE_A_PEER, __WGDEVICE_A_LAST }; @@ -201,6 +218,7 @@ enum wgpeer_flag { WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1, WGPEER_F_UPDATE_ONLY = 1U << 2, WGPEER_F_HAS_ADVANCED_SECURITY = 1U << 3, + WGPEER_F_HAS_SPECIAL_HANDSHAKE = 1U << 4, __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS | WGPEER_F_UPDATE_ONLY }; @@ -217,6 +235,7 @@ enum wgpeer_attribute { WGPEER_A_ALLOWEDIPS, WGPEER_A_PROTOCOL_VERSION, WGPEER_A_ADVANCED_SECURITY, + WGPEER_A_SPECIAL_HANDSHAKE, __WGPEER_A_LAST }; #define WGPEER_A_MAX (__WGPEER_A_LAST - 1) diff --git a/src/uapi/openbsd/net/if_wg.h b/src/uapi/openbsd/net/if_wg.h index f768a32..1f30572 100644 --- a/src/uapi/openbsd/net/if_wg.h +++ b/src/uapi/openbsd/net/if_wg.h @@ -67,20 +67,31 @@ struct wg_peer_io { struct wg_aip_io p_aips[]; }; -#define WG_INTERFACE_HAS_PUBLIC (1 << 0) -#define WG_INTERFACE_HAS_PRIVATE (1 << 1) -#define WG_INTERFACE_HAS_PORT (1 << 2) -#define WG_INTERFACE_HAS_RTABLE (1 << 3) -#define WG_INTERFACE_REPLACE_PEERS (1 << 4) -#define WG_INTERFACE_DEVICE_HAS_JC (1 << 5) +#define WG_INTERFACE_HAS_PUBLIC (1 << 0) +#define WG_INTERFACE_HAS_PRIVATE (1 << 1) +#define WG_INTERFACE_HAS_PORT (1 << 2) +#define WG_INTERFACE_HAS_RTABLE (1 << 3) +#define WG_INTERFACE_REPLACE_PEERS (1 << 4) +#define WG_INTERFACE_DEVICE_HAS_JC (1 << 5) #define WG_INTERFACE_DEVICE_HAS_JMIN (1 << 6) #define WG_INTERFACE_DEVICE_HAS_JMAX (1 << 7) -#define WG_INTERFACE_DEVICE_HAS_S1 (1 << 8) -#define WG_INTERFACE_DEVICE_HAS_S2 (1 << 9) -#define WG_INTERFACE_DEVICE_HAS_H1 (1 << 10) -#define WG_INTERFACE_DEVICE_HAS_H2 (1 << 11) -#define WG_INTERFACE_DEVICE_HAS_H3 (1 << 12) -#define WG_INTERFACE_DEVICE_HAS_H4 (1 << 13) +#define WG_INTERFACE_DEVICE_HAS_S1 (1 << 8) +#define WG_INTERFACE_DEVICE_HAS_S2 (1 << 9) +#define WG_INTERFACE_DEVICE_HAS_S3 (1 << 10) +#define WG_INTERFACE_DEVICE_HAS_S4 (1 << 11) +#define WG_INTERFACE_DEVICE_HAS_H1 (1 << 12) +#define WG_INTERFACE_DEVICE_HAS_H2 (1 << 13) +#define WG_INTERFACE_DEVICE_HAS_H3 (1 << 14) +#define WG_INTERFACE_DEVICE_HAS_H4 (1 << 15) +#define WG_INTERFACE_DEVICE_HAS_I1 (1 << 16) +#define WG_INTERFACE_DEVICE_HAS_I2 (1 << 17) +#define WG_INTERFACE_DEVICE_HAS_I3 (1 << 18) +#define WG_INTERFACE_DEVICE_HAS_I4 (1 << 19) +#define WG_INTERFACE_DEVICE_HAS_I5 (1 << 20) +#define WG_INTERFACE_DEVICE_HAS_J1 (1 << 21) +#define WG_INTERFACE_DEVICE_HAS_J2 (1 << 22) +#define WG_INTERFACE_DEVICE_HAS_J3 (1 << 23) +#define WG_INTERFACE_DEVICE_HAS_ITIME (1 << 24) struct wg_interface_io { uint16_t i_flags; @@ -96,10 +107,22 @@ struct wg_interface_io { uint16_t i_junk_packet_max_size; uint16_t i_init_packet_junk_size; uint16_t i_response_packet_junk_size; + uint16_t i_cookie_reply_packet_junk_size; + uint16_t i_transport_packet_junk_size; uint32_t i_init_packet_magic_header; uint32_t i_response_packet_magic_header; uint32_t i_underload_packet_magic_header; uint32_t i_transport_packet_magic_header; + + uint8_t* i_i1; + uint8_t* i_i2; + uint8_t* i_i3; + uint8_t* i_i4; + uint8_t* i_i5; + uint8_t* i_j1; + uint8_t* i_j2; + uint8_t* i_j3; + uint32_t i_itime; }; struct wg_data_io { diff --git a/src/uapi/windows/wireguard.h b/src/uapi/windows/wireguard.h index 917d785..a076b46 100644 --- a/src/uapi/windows/wireguard.h +++ b/src/uapi/windows/wireguard.h @@ -63,10 +63,21 @@ typedef enum WG_IOCTL_INTERFACE_JMAX = 1 << 7, WG_IOCTL_INTERFACE_S1 = 1 << 8, WG_IOCTL_INTERFACE_S2 = 1 << 9, - WG_IOCTL_INTERFACE_H1 = 1 << 10, - WG_IOCTL_INTERFACE_H2 = 1 << 11, - WG_IOCTL_INTERFACE_H3 = 1 << 12, - WG_IOCTL_INTERFACE_H4 = 1 << 13 + WG_IOCTL_INTERFACE_S3 = 1 << 10, + WG_IOCTL_INTERFACE_S4 = 1 << 11, + WG_IOCTL_INTERFACE_H1 = 1 << 12, + WG_IOCTL_INTERFACE_H2 = 1 << 12, + WG_IOCTL_INTERFACE_H3 = 1 << 13, + WG_IOCTL_INTERFACE_H4 = 1 << 14, + WG_IOCTL_INTERFACE_I1 = 1U << 15, + WG_IOCTL_INTERFACE_I2 = 1U << 16, + WG_IOCTL_INTERFACE_I3 = 1U << 17, + WG_IOCTL_INTERFACE_I4 = 1U << 18, + WG_IOCTL_INTERFACE_I5 = 1U << 19, + WG_IOCTL_INTERFACE_J1 = 1U << 20, + WG_IOCTL_INTERFACE_J2 = 1U << 21, + WG_IOCTL_INTERFACE_J3 = 1U << 22, + WG_IOCTL_INTERFACE_ITIME = 1U << 23 } WG_IOCTL_INTERFACE_FLAG; typedef struct _WG_IOCTL_INTERFACE @@ -81,10 +92,22 @@ typedef struct _WG_IOCTL_INTERFACE USHORT JunkPacketMaxSize; USHORT InitPacketJunkSize; USHORT ResponsePacketJunkSize; + USHORT CookieReplyPacketJunkSize; + USHORT TransportPacketJunkSize; ULONG InitPacketMagicHeader; ULONG ResponsePacketMagicHeader; ULONG UnderloadPacketMagicHeader; ULONG TransportPacketMagicHeader; + + UCHAR* I1; + UCHAR* I2; + UCHAR* I3; + UCHAR* I4; + UCHAR* I5; + UCHAR* J1; + UCHAR* J2; + UCHAR* J3; + ULONG Itime; } __attribute__((aligned(8))) WG_IOCTL_INTERFACE; #define WG_IOCTL_GET CTL_CODE(45208U, 321, METHOD_OUT_DIRECT, FILE_READ_DATA | FILE_WRITE_DATA) diff --git a/src/wg-quick/android.c b/src/wg-quick/android.c index 425a068..167c6d6 100644 --- a/src/wg-quick/android.c +++ b/src/wg-quick/android.c @@ -42,6 +42,7 @@ static bool is_exiting = false; static bool binder_available = false; static unsigned int sdk_version; static bool is_asecurity_on = false; +static bool is_special_handshake_on = false; static void *xmalloc(size_t size) { @@ -633,7 +634,7 @@ static void auto_su(int argc, char *argv[]) static void add_if(const char *iface) { - if (is_asecurity_on) + if (is_asecurity_on || is_special_handshake_on) cmd("amneziawg-go %s", iface); else cmd("ip link add %s type amneziawg", iface); @@ -1278,6 +1279,24 @@ static void parse_options(char **iface, char **config, unsigned int *mtu, char * is_asecurity_on = true; } else if (!strncasecmp(clean, "H4=", 3) && j > 4) { is_asecurity_on = true; + } else if (!strncasecmp(clean, "I1=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "I2=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "I3=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "I4=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "I5=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "J1=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "J2=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "J3=", 3) && j > 4) { + is_special_handshake_on = true; + } else if (!strncasecmp(clean, "Itime=", 6) && j > 4) { + is_special_handshake_on = true; } } *config = concat_and_free(*config, "", line); @@ -1322,4 +1341,4 @@ int main(int argc, char *argv[]) return 1; } return 0; -} \ No newline at end of file +} diff --git a/src/wg.c b/src/wg.c index 6480970..0431fce 100644 --- a/src/wg.c +++ b/src/wg.c @@ -42,7 +42,7 @@ int main(int argc, const char *argv[]) PROG_NAME = argv[0]; if (argc == 2 && (!strcmp(argv[1], "-v") || !strcmp(argv[1], "--version") || !strcmp(argv[1], "version"))) { - printf("wireguard-tools v%s - https://git.zx2c4.com/wireguard-tools/\n", WIREGUARD_TOOLS_VERSION); + printf("amneziawg-tools v%s - https://amnezia.org\n", WIREGUARD_TOOLS_VERSION); return 0; } if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "help"))) { From dbd48bde71bf06e33d419b0caeffc817822b33f6 Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Tue, 15 Jul 2025 06:30:51 +0200 Subject: [PATCH 2/8] fix: minor issues with new params --- contrib/json/wg-json | 4 +++- src/ipc-linux.h | 2 +- src/ipc-openbsd.h | 2 +- src/ipc-windows.h | 27 +++++++++------------------ src/set.c | 2 +- src/show.c | 12 +++++++++++- src/wg-quick/android.c | 4 ++++ 7 files changed, 30 insertions(+), 23 deletions(-) diff --git a/contrib/json/wg-json b/contrib/json/wg-json index d24296a..971f199 100755 --- a/contrib/json/wg-json +++ b/contrib/json/wg-json @@ -11,7 +11,7 @@ while read -r -d $'\t' device; do if [[ $device != "$last_device" ]]; then [[ -z $last_device ]] && printf '\n' || printf '%s,\n' "$end" last_device="$device" - read -r private_key public_key listen_port jc jmin jmax s1 s2 h1 h2 h3 h4 i1 i2 i3 i4 i5 j1 j2 j3 itime fwmark + read -r private_key public_key listen_port jc jmin jmax s1 s2 s3 s4 h1 h2 h3 h4 i1 i2 i3 i4 i5 j1 j2 j3 itime fwmark printf '\t"%s": {' "$device" delim=$'\n' [[ $private_key == "(none)" ]] || { printf '%s\t\t"privateKey": "%s"' "$delim" "$private_key"; delim=$',\n'; } @@ -22,6 +22,8 @@ while read -r -d $'\t' device; do [[ $jmax == "0" ]] || { printf '%s\t\t"jmax": %u' "$delim" $(( $jmax )); delim=$',\n'; } [[ $s1 == "0" ]] || { printf '%s\t\t"s1": %u' "$delim" $(( $s1 )); delim=$',\n'; } [[ $s2 == "0" ]] || { printf '%s\t\t"s2": %u' "$delim" $(( $s2 )); delim=$',\n'; } + [[ $s3 == "0" ]] || { printf '%s\t\t"s3": %u' "$delim" $(( $s3 )); delim=$',\n'; } + [[ $s4 == "0" ]] || { printf '%s\t\t"s4": %u' "$delim" $(( $s4 )); delim=$',\n'; } [[ $h1 == "1" ]] || { printf '%s\t\t"h1": %u' "$delim" $(( $h1 )); delim=$',\n'; } [[ $h2 == "2" ]] || { printf '%s\t\t"h2": %u' "$delim" $(( $h2 )); delim=$',\n'; } [[ $h3 == "3" ]] || { printf '%s\t\t"h3": %u' "$delim" $(( $h3 )); delim=$',\n'; } diff --git a/src/ipc-linux.h b/src/ipc-linux.h index 0531ff5..8c082a3 100644 --- a/src/ipc-linux.h +++ b/src/ipc-linux.h @@ -653,7 +653,7 @@ static int parse_device(const struct nlattr *attr, void *data) } break; case WGDEVICE_A_ITIME: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) + if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { device->itime = mnl_attr_get_u32(attr); device->flags |= WGDEVICE_HAS_ITIME; diff --git a/src/ipc-openbsd.h b/src/ipc-openbsd.h index dd063ae..61bac7f 100644 --- a/src/ipc-openbsd.h +++ b/src/ipc-openbsd.h @@ -215,7 +215,7 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_ITIME) { - dev->itime = wg_iface->i_itime ; + dev->itime = wg_iface->i_itime; dev->flags |= WGDEVICE_HAS_ITIME; } diff --git a/src/ipc-windows.h b/src/ipc-windows.h index faa8b8f..3756a52 100644 --- a/src/ipc-windows.h +++ b/src/ipc-windows.h @@ -307,64 +307,55 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) dev->transport_packet_magic_header = wg_iface->TransportPacketMagicHeader; dev->flags |= WGDEVICE_HAS_H4; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_I1) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I1) { const size_t i1_size = strlen((char*)wg_iface->I1) + 1; dev->i1 = (char*)malloc(i1_size); memcpy(dev->i1, wg_iface->I1, i1_size); dev->flags |= WGDEVICE_HAS_I1; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_I2) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I2) { const size_t i2_size = strlen((char*)wg_iface->I2) + 1; dev->i2 = (char*)malloc(i2_size); memcpy(dev->i2, wg_iface->I2, i2_size); dev->flags |= WGDEVICE_HAS_I2; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_I3) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I3) { const size_t i3_size = strlen((char*)wg_iface->I3) + 1; dev->i3 = (char*)malloc(i3_size); memcpy(dev->i3, wg_iface->I3, i3_size); dev->flags |= WGDEVICE_HAS_I3; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_I4) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I4) { const size_t i4_size = strlen((char*)wg_iface->I4) + 1; dev->i4 = (char*)malloc(i4_size); memcpy(dev->i4, wg_iface->I4, i4_size); dev->flags |= WGDEVICE_HAS_I4; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_I5) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_I5) { const size_t i5_size = strlen((char*)wg_iface->I5) + 1; dev->i5 = (char*)malloc(i5_size); memcpy(dev->i5, wg_iface->I5, i5_size); dev->flags |= WGDEVICE_HAS_I5; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_J1) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_J1) { const size_t j1_size = strlen((char*)wg_iface->J1) + 1; dev->j1 = (char*)malloc(j1_size); memcpy(dev->j1, wg_iface->J1, j1_size); dev->flags |= WGDEVICE_HAS_J1; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_J2) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_J2) { const size_t j2_size = strlen((char*)wg_iface->J2) + 1; dev->j2 = (char*)malloc(j2_size); memcpy(dev->j2, wg_iface->J2, j2_size); dev->flags |= WGDEVICE_HAS_J2; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_J3) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_J3) { const size_t j3_size = strlen((char*)wg_iface->J3) + 1; dev->j3 = (char*)malloc(j3_size); memcpy(dev->j3, wg_iface->J3, j3_size); dev->flags |= WGDEVICE_HAS_J3; } - if (wg_iface->Flags & WG_IOCTL_INTERFACE_ITIME) - { + if (wg_iface->Flags & WG_IOCTL_INTERFACE_ITIME) { dev->itime = wg_iface->Itime; dev->flags |= WGDEVICE_HAS_ITIME; } diff --git a/src/set.c b/src/set.c index 6bec30a..dc56667 100644 --- a/src/set.c +++ b/src/set.c @@ -18,7 +18,7 @@ int set_main(int argc, const char *argv[]) int ret = 1; if (argc < 3) { - fprintf(stderr, "Usage: %s %s [listen-port ] [fwmark ] [private-key ] [jc ] [jmin ] [jmax ] [s1 ] [s2 ] [h1 ] [h2 ] [h3 ] [h4 ] [i1 \"\"] [i2 \"\"] [i3 \"\"] [i4 \"\"] [i5 \"\"] [j1 \"\"] [j2 \"\"] [j3 \"\"] [itime ][peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips /[,/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); + fprintf(stderr, "Usage: %s %s [listen-port ] [fwmark ] [private-key ] [jc ] [jmin ] [jmax ] [s1 ] [s2 ] [s3 ] [s4 ] [h1 ] [h2 ] [h3 ] [h4 ] [i1 \"\"] [i2 \"\"] [i3 \"\"] [i4 \"\"] [i5 \"\"] [j1 \"\"] [j2 \"\"] [j3 \"\"] [itime ][peer [remove] [preshared-key ] [endpoint :] [persistent-keepalive ] [allowed-ips /[,/] [advanced-security ]...] ]...\n", PROG_NAME, argv[0]); return 1; } diff --git a/src/show.c b/src/show.c index 9b047c9..93e1b03 100644 --- a/src/show.c +++ b/src/show.c @@ -202,7 +202,7 @@ static char *bytes(uint64_t b) static const char *COMMAND_NAME; static void show_usage(void) { - fprintf(stderr, "Usage: %s %s { | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump | jc | jmin | jmax | s1 | s2 | h1 | h2 | h3 | h4 | i1 | i2 | i3 | i4 | i5 | j1 | j2 | j3 | itime]\n", PROG_NAME, COMMAND_NAME); + fprintf(stderr, "Usage: %s %s { | all | interfaces } [public-key | private-key | listen-port | fwmark | peers | preshared-keys | endpoints | allowed-ips | latest-handshakes | transfer | persistent-keepalive | dump | jc | jmin | jmax | s1 | s2 | s3 | s4 | h1 | h2 | h3 | h4 | i1 | i2 | i3 | i4 | i5 | j1 | j2 | j3 | itime]\n", PROG_NAME, COMMAND_NAME); } static void pretty_print(struct wgdevice *device) @@ -306,6 +306,8 @@ static void dump_print(struct wgdevice *device, bool with_interface) printf("%u\t", device->junk_packet_max_size); printf("%u\t", device->init_packet_junk_size); printf("%u\t", device->response_packet_junk_size); + printf("%u\t", device->cookie_reply_packet_junk_size); + printf("%u\t", device->transport_packet_junk_size); printf("%u\t", device->init_packet_magic_header); printf("%u\t", device->response_packet_magic_header); printf("%u\t", device->underload_packet_magic_header); @@ -391,6 +393,14 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int if (with_interface) printf("%s\t", device->name); printf("%u\n", device->response_packet_junk_size); + } else if(!strcmp(param, "s3")) { + if (with_interface) + printf("%s\t", device->name); + printf("%u\n", device->cookie_reply_packet_junk_size); + } else if(!strcmp(param, "s4")) { + if (with_interface) + printf("%s\t", device->name); + printf("%u\n", device->transport_packet_junk_size); } else if(!strcmp(param, "h1")) { if (with_interface) printf("%s\t", device->name); diff --git a/src/wg-quick/android.c b/src/wg-quick/android.c index 167c6d6..dd3a340 100644 --- a/src/wg-quick/android.c +++ b/src/wg-quick/android.c @@ -1271,6 +1271,10 @@ static void parse_options(char **iface, char **config, unsigned int *mtu, char * is_asecurity_on = true; } else if (!strncasecmp(clean, "S2=", 3) && j > 4) { is_asecurity_on = true; + } else if (!strncasecmp(clean, "S3=", 3) && j > 4) { + is_asecurity_on = true; + } else if (!strncasecmp(clean, "S4=", 3) && j > 4) { + is_asecurity_on = true; } else if (!strncasecmp(clean, "H1=", 3) && j > 4) { is_asecurity_on = true; } else if (!strncasecmp(clean, "H2=", 3) && j > 4) { From bb9f1632cd8eaeec6b0c9797a14f7bce1dbdfa06 Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Tue, 15 Jul 2025 06:31:20 +0200 Subject: [PATCH 3/8] fix: special handshake clean line --- src/config.c | 58 +++++++++++++++++++++++++++++++++------------------- src/config.h | 1 + 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/config.c b/src/config.c index a2b35f1..c5cfb89 100644 --- a/src/config.c +++ b/src/config.c @@ -23,7 +23,7 @@ #define COMMENT_CHAR '#' // Keys that should return empty string instead of NULL when not found -static const char *awg_optional_keys[] = { +static const char *awg_special_handshake_keys[] = { "I1", "I2", "I3", "I4", "I5", "J1", "J2", "J3", NULL @@ -425,7 +425,7 @@ static inline bool parse_awg_string(char **device_value, const char *name, const return true; } - if( len >= MAX_AWG_JUNK_LEN) { + if (len >= MAX_AWG_JUNK_LEN) { fprintf(stderr, "Unable to process string for: %s; longer than: %d\n", name, MAX_AWG_JUNK_LEN); return false; } @@ -627,13 +627,6 @@ static bool process_line(struct config_ctx *ctx, const char *line) if (ret) ctx->device->flags |= WGDEVICE_HAS_ITIME; } else { - // Check if this is an AWG optional key - if (strlen(line) == 3) { - for (int i = 0; awg_optional_keys[i] != NULL; i++) { - if (!strncasecmp(line, awg_optional_keys[i], 2)) - return true; - } - } goto error; } } else if (ctx->is_peer_section) { @@ -677,9 +670,6 @@ bool config_read_line(struct config_ctx *ctx, const char *input) size_t len, cleaned_len = 0; char *line, *comment; bool ret = true; - bool found_equals = false; - bool found_value_start = false; - size_t value_end = 0; /* This is what strchrnul is for, but that isn't portable. */ comment = strchr(input, COMMENT_CHAR); @@ -695,6 +685,40 @@ bool config_read_line(struct config_ctx *ctx, const char *input) goto out; } + bool is_awg_special_handshake_key = false; + for (size_t i = 0; awg_special_handshake_keys[i] != NULL; i++) { + if (!strncasecmp(input, awg_special_handshake_keys[i], 2)) { + is_awg_special_handshake_key = true; + break; + } + } + + if (is_awg_special_handshake_key) { + cleaned_len = clean_special_handshake_line(input, len, line); + } else { + for (size_t i = 0; i < len; ++i) { + if (!char_is_space(input[i])) { + line[cleaned_len++] = input[i]; + } + } + } + + + if (!cleaned_len) + goto out; + ret = process_line(ctx, line); +out: + free(line); + if (!ret) + free_wgdevice(ctx->device); + return ret; +} + +size_t clean_special_handshake_line(const char *input, size_t len, char *line) +{ + size_t cleaned_len = 0, value_end = 0; + bool found_equals = false, found_value_start = false; + /* Remove preceding and trailing whitespaces before value First pass: find the actual end of the value (trim trailing spaces) */ for (size_t i = len; i > 0; --i) { @@ -725,15 +749,7 @@ bool config_read_line(struct config_ctx *ctx, const char *input) line[cleaned_len++] = input[i]; } } - - if (!cleaned_len) - goto out; - ret = process_line(ctx, line); -out: - free(line); - if (!ret) - free_wgdevice(ctx->device); - return ret; + return cleaned_len; } bool config_read_init(struct config_ctx *ctx, bool append) diff --git a/src/config.h b/src/config.h index 443cf21..87efcf4 100644 --- a/src/config.h +++ b/src/config.h @@ -19,6 +19,7 @@ struct config_ctx { bool is_peer_section, is_device_section; }; +size_t clean_special_handshake_line(const char *input, size_t len, char *line); struct wgdevice *config_read_cmd(const char *argv[], int argc); bool config_read_init(struct config_ctx *ctx, bool append); bool config_read_line(struct config_ctx *ctx, const char *line); From 4b25e43d6722ff7cfe67eb74a5f31d8acee9c26b Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Fri, 18 Jul 2025 04:50:40 +0200 Subject: [PATCH 4/8] feat: ranged magic header --- contrib/json/wg-json | 8 +++---- src/config.c | 16 ++++++------- src/containers.h | 8 +++---- src/ipc-freebsd.h | 36 ++++++++++++++++------------- src/ipc-linux.h | 16 ++++++------- src/ipc-openbsd.h | 16 ++++++------- src/ipc-uapi.h | 16 ++++++------- src/ipc-windows.h | 32 ++++++++++++++++++------- src/show.c | 24 +++++++++---------- src/showconf.c | 8 +++---- src/uapi/openbsd/net/if_wg.h | 8 +++---- src/uapi/windows/wireguard.h | 8 +++---- src/wg-quick/android.c | 45 ++++++++++++++++++------------------ src/wg-quick/freebsd.bash | 19 +++++++++++---- src/wg-quick/openbsd.bash | 19 +++++++++++---- 15 files changed, 160 insertions(+), 119 deletions(-) diff --git a/contrib/json/wg-json b/contrib/json/wg-json index 971f199..3778b1d 100755 --- a/contrib/json/wg-json +++ b/contrib/json/wg-json @@ -24,10 +24,10 @@ while read -r -d $'\t' device; do [[ $s2 == "0" ]] || { printf '%s\t\t"s2": %u' "$delim" $(( $s2 )); delim=$',\n'; } [[ $s3 == "0" ]] || { printf '%s\t\t"s3": %u' "$delim" $(( $s3 )); delim=$',\n'; } [[ $s4 == "0" ]] || { printf '%s\t\t"s4": %u' "$delim" $(( $s4 )); delim=$',\n'; } - [[ $h1 == "1" ]] || { printf '%s\t\t"h1": %u' "$delim" $(( $h1 )); delim=$',\n'; } - [[ $h2 == "2" ]] || { printf '%s\t\t"h2": %u' "$delim" $(( $h2 )); delim=$',\n'; } - [[ $h3 == "3" ]] || { printf '%s\t\t"h3": %u' "$delim" $(( $h3 )); delim=$',\n'; } - [[ $h4 == "4" ]] || { printf '%s\t\t"h4": %u' "$delim" $(( $h4 )); delim=$',\n'; } + [[ $h1 == "1" ]] || { printf '%s\t\t"h1": %s' "$delim" $(( $h1 )); delim=$',\n'; } + [[ $h2 == "2" ]] || { printf '%s\t\t"h2": %s' "$delim" $(( $h2 )); delim=$',\n'; } + [[ $h3 == "3" ]] || { printf '%s\t\t"h3": %s' "$delim" $(( $h3 )); delim=$',\n'; } + [[ $h4 == "4" ]] || { printf '%s\t\t"h4": %s' "$delim" $(( $h4 )); delim=$',\n'; } [[ $i1 == "(none)" ]] || { printf '%s\t\t"i1": "%s"' "$delim" "$i1"; delim=$',\n'; } [[ $i2 == "(none)" ]] || { printf '%s\t\t"i2": "%s"' "$delim" "$i2"; delim=$',\n'; } [[ $i3 == "(none)" ]] || { printf '%s\t\t"i3": "%s"' "$delim" "$i3"; delim=$',\n'; } diff --git a/src/config.c b/src/config.c index c5cfb89..6aa31b0 100644 --- a/src/config.c +++ b/src/config.c @@ -575,19 +575,19 @@ static bool process_line(struct config_ctx *ctx, const char *line) if (ret) ctx->device->flags |= WGDEVICE_HAS_S4; } else if (key_match("H1")) { - ret = parse_uint32(&ctx->device->init_packet_magic_header, "H1", value); + ret = parse_awg_string(&ctx->device->init_packet_magic_header, "H1", value); if (ret) ctx->device->flags |= WGDEVICE_HAS_H1; } else if (key_match("H2")) { - ret = parse_uint32(&ctx->device->response_packet_magic_header, "H2", value); + ret = parse_awg_string(&ctx->device->response_packet_magic_header, "H2", value); if (ret) ctx->device->flags |= WGDEVICE_HAS_H2; } else if (key_match("H3")) { - ret = parse_uint32(&ctx->device->underload_packet_magic_header, "H3", value); + ret = parse_awg_string(&ctx->device->underload_packet_magic_header, "H3", value); if (ret) ctx->device->flags |= WGDEVICE_HAS_H3; } else if (key_match("H4")) { - ret = parse_uint32(&ctx->device->transport_packet_magic_header, "H4", value); + ret = parse_awg_string(&ctx->device->transport_packet_magic_header, "H4", value); if (ret) ctx->device->flags |= WGDEVICE_HAS_H4; } else if (key_match("I1")) { @@ -876,28 +876,28 @@ struct wgdevice *config_read_cmd(const char *argv[], int argc) argv += 2; argc -= 2; } else if (!strcmp(argv[0], "h1") && argc >= 2 && !peer) { - if (!parse_uint32(&device->init_packet_magic_header, "h1", argv[1])) + if (!parse_awg_string(&device->init_packet_magic_header, "h1", argv[1])) goto error; device->flags |= WGDEVICE_HAS_H1; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "h2") && argc >= 2 && !peer) { - if (!parse_uint32(&device->response_packet_magic_header, "h2", argv[1])) + if (!parse_awg_string(&device->response_packet_magic_header, "h2", argv[1])) goto error; device->flags |= WGDEVICE_HAS_H2; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "h3") && argc >= 2 && !peer) { - if (!parse_uint32(&device->underload_packet_magic_header, "h3", argv[1])) + if (!parse_awg_string(&device->underload_packet_magic_header, "h3", argv[1])) goto error; device->flags |= WGDEVICE_HAS_H3; argv += 2; argc -= 2; } else if (!strcmp(argv[0], "h4") && argc >= 2 && !peer) { - if (!parse_uint32(&device->transport_packet_magic_header, "h4", argv[1])) + if (!parse_awg_string(&device->transport_packet_magic_header, "h4", argv[1])) goto error; device->flags |= WGDEVICE_HAS_H4; diff --git a/src/containers.h b/src/containers.h index 09ff619..21f22a0 100644 --- a/src/containers.h +++ b/src/containers.h @@ -125,10 +125,10 @@ struct wgdevice { uint16_t response_packet_junk_size; uint16_t cookie_reply_packet_junk_size; uint16_t transport_packet_junk_size; - uint32_t init_packet_magic_header; - uint32_t response_packet_magic_header; - uint32_t underload_packet_magic_header; - uint32_t transport_packet_magic_header; + char* init_packet_magic_header; + char* response_packet_magic_header; + char* underload_packet_magic_header; + char* transport_packet_magic_header; char* i1; char* i2; char* i3; diff --git a/src/ipc-freebsd.h b/src/ipc-freebsd.h index 206ebcd..5773937 100644 --- a/src/ipc-freebsd.h +++ b/src/ipc-freebsd.h @@ -141,30 +141,34 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) } } if (nvlist_exists_number(nvl_device, "h1")) { - number = nvlist_get_number(nvl_device, "h1"); - if (number <= UINT32_MAX){ - dev->init_packet_magic_header = number; + binary = nvlist_get_binary(nvl_device, "h1", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->init_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H1; } } if (nvlist_exists_number(nvl_device, "h2")) { - number = nvlist_get_number(nvl_device, "h2"); - if (number <= UINT32_MAX){ - dev->response_packet_magic_header = number; + binary = nvlist_get_binary(nvl_device, "h2", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->response_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H2; } } if (nvlist_exists_number(nvl_device, "h3")) { - number = nvlist_get_number(nvl_device, "h3"); - if (number <= UINT32_MAX){ - dev->underload_packet_magic_header = number; + binary = nvlist_get_binary(nvl_device, "h3", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->underload_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H3; } } if (nvlist_exists_number(nvl_device, "h4")) { - number = nvlist_get_number(nvl_device, "h4"); - if (number <= UINT32_MAX){ - dev->transport_packet_magic_header = number; + binary = nvlist_get_binary(nvl_device, "h4", &size); + if (binary && size < MAX_AWG_JUNK_LEN) + { + dev->transport_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H4; } } @@ -446,13 +450,13 @@ static int kernel_set_device(struct wgdevice *dev) if (dev->flags & WGDEVICE_HAS_S4) nvlist_add_number(nvl_device, "s4", dev->transport_packet_junk_size); if (dev->flags & WGDEVICE_HAS_H1) - nvlist_add_number(nvl_device, "h1", dev->init_packet_magic_header); + nvlist_add_binary(nvl_device, "h1", dev->init_packet_magic_header, strlen(dev->h1) + 1); if (dev->flags & WGDEVICE_HAS_H2) - nvlist_add_number(nvl_device, "h2", dev->response_packet_magic_header); + nvlist_add_binary(nvl_device, "h2", dev->response_packet_magic_header, strlen(dev->h2) + 1); if (dev->flags & WGDEVICE_HAS_H3) - nvlist_add_number(nvl_device, "h3", dev->underload_packet_magic_header); + nvlist_add_binary(nvl_device, "h3", dev->underload_packet_magic_header, strlen(dev->h3) + 1); if (dev->flags & WGDEVICE_HAS_H4) - nvlist_add_number(nvl_device, "h4", dev->transport_packet_magic_header); + nvlist_add_binary(nvl_device, "h4", dev->transport_packet_magic_header, strlen(dev->h4) + 1); if (dev->flags & WGDEVICE_HAS_I1) nvlist_add_binary(nvl_device, "i1", dev->i1, strlen(dev->i1) + 1); if (dev->flags & WGDEVICE_HAS_I2) diff --git a/src/ipc-linux.h b/src/ipc-linux.h index 8c082a3..09bf48a 100644 --- a/src/ipc-linux.h +++ b/src/ipc-linux.h @@ -178,13 +178,13 @@ again: if (dev->flags & WGDEVICE_HAS_S4) mnl_attr_put_u16(nlh, WGDEVICE_A_S4, dev->transport_packet_junk_size); if (dev->flags & WGDEVICE_HAS_H1) - mnl_attr_put_u32(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header); + mnl_attr_put_strz(nlh, WGDEVICE_A_H1, dev->init_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H2) - mnl_attr_put_u32(nlh, WGDEVICE_A_H2, dev->response_packet_magic_header); + mnl_attr_put_strz(nlh, WGDEVICE_A_H2, dev->response_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H3) - mnl_attr_put_u32(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header); + mnl_attr_put_strz(nlh, WGDEVICE_A_H3, dev->underload_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H4) - mnl_attr_put_u32(nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header); + mnl_attr_put_strz(nlh, WGDEVICE_A_H4, dev->transport_packet_magic_header); if (dev->flags & WGDEVICE_HAS_I1) mnl_attr_put_strz(nlh, WGDEVICE_A_I1, dev->i1); if (dev->flags & WGDEVICE_HAS_I2) @@ -574,25 +574,25 @@ static int parse_device(const struct nlattr *attr, void *data) break; case WGDEVICE_A_H1: if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { - device->init_packet_magic_header = mnl_attr_get_u32(attr); + device->init_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H1; } break; case WGDEVICE_A_H2: if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { - device->response_packet_magic_header = mnl_attr_get_u32(attr); + device->response_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H2; } break; case WGDEVICE_A_H3: if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { - device->underload_packet_magic_header = mnl_attr_get_u32(attr); + device->underload_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H3; } break; case WGDEVICE_A_H4: if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { - device->transport_packet_magic_header = mnl_attr_get_u32(attr); + device->transport_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H4; } break; diff --git a/src/ipc-openbsd.h b/src/ipc-openbsd.h index 61bac7f..383de9b 100644 --- a/src/ipc-openbsd.h +++ b/src/ipc-openbsd.h @@ -146,22 +146,22 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H1) { - dev->init_packet_magic_header = wg_iface->i_init_packet_magic_header; + dev->init_packet_magic_header = strdup(wg_iface->i_init_packet_magic_header); dev->flags |= WGDEVICE_HAS_H1; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H2) { - dev->response_packet_magic_header = wg_iface->i_response_packet_magic_header; + dev->response_packet_magic_header = strdup(wg_iface->i_response_packet_magic_header); dev->flags |= WGDEVICE_HAS_H2; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H3) { - dev->underload_packet_magic_header = wg_iface->i_underload_packet_magic_header; + dev->underload_packet_magic_header = strdup(wg_iface->i_underload_packet_magic_header); dev->flags |= WGDEVICE_HAS_H3; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H4) { - dev->transport_packet_magic_header = wg_iface->i_transport_packet_magic_header; + dev->transport_packet_magic_header = strdup(wg_iface->i_transport_packet_magic_header); dev->flags |= WGDEVICE_HAS_H4; } @@ -367,22 +367,22 @@ static int kernel_set_device(struct wgdevice *dev) } if (dev->flags & WGDEVICE_HAS_H1) { - wg_iface->i_init_packet_magic_header = dev->init_packet_magic_header; + wg_iface->i_init_packet_magic_header = strdup(dev->init_packet_magic_header); wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H1; } if (dev->flags & WGDEVICE_HAS_H2) { - wg_iface->i_response_packet_magic_header = dev->response_packet_magic_header; + wg_iface->i_response_packet_magic_header = strdup(dev->response_packet_magic_header); wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H2; } if (dev->flags & WGDEVICE_HAS_H3) { - wg_iface->i_underload_packet_magic_header = dev->underload_packet_magic_header; + wg_iface->i_underload_packet_magic_header = strdup(dev->underload_packet_magic_header); wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H3; } if (dev->flags & WGDEVICE_HAS_H4) { - wg_iface->i_transport_packet_magic_header = dev->transport_packet_magic_header; + wg_iface->i_transport_packet_magic_header = strdup(dev->transport_packet_magic_header); wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H4; } diff --git a/src/ipc-uapi.h b/src/ipc-uapi.h index 32be0d8..74640a6 100644 --- a/src/ipc-uapi.h +++ b/src/ipc-uapi.h @@ -66,13 +66,13 @@ static int userspace_set_device(struct wgdevice *dev) if (dev->flags & WGDEVICE_HAS_S4) fprintf(f, "s4=%u\n", dev->transport_packet_junk_size); if (dev->flags & WGDEVICE_HAS_H1) - fprintf(f, "h1=%u\n", dev->init_packet_magic_header); + fprintf(f, "h1=%s\n", dev->init_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H2) - fprintf(f, "h2=%u\n", dev->response_packet_magic_header); + fprintf(f, "h2=%s\n", dev->response_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H3) - fprintf(f, "h3=%u\n", dev->underload_packet_magic_header); + fprintf(f, "h3=%s\n", dev->underload_packet_magic_header); if (dev->flags & WGDEVICE_HAS_H4) - fprintf(f, "h4=%u\n", dev->transport_packet_magic_header); + fprintf(f, "h4=%s\n", dev->transport_packet_magic_header); if (dev->flags & WGDEVICE_HAS_I1) fprintf(f, "i1=%s\n", dev->i1); @@ -255,16 +255,16 @@ static int userspace_get_device(struct wgdevice **out, const char *iface) dev->transport_packet_junk_size = NUM(0xffffU); dev->flags |= WGDEVICE_HAS_S4; } else if(!peer && !strcmp(key, "h1")) { - dev->init_packet_magic_header = NUM(0xffffffffU); + dev->init_packet_magic_header = strdup(value); dev->flags |= WGDEVICE_HAS_H1; } else if(!peer && !strcmp(key, "h2")) { - dev->response_packet_magic_header = NUM(0xffffffffU); + dev->response_packet_magic_header = strdup(value); dev->flags |= WGDEVICE_HAS_H2; } else if(!peer && !strcmp(key, "h3")) { - dev->underload_packet_magic_header = NUM(0xffffffffU); + dev->underload_packet_magic_header = strdup(value); dev->flags |= WGDEVICE_HAS_H3; } else if(!peer && !strcmp(key, "h4")) { - dev->transport_packet_magic_header = NUM(0xffffffffU); + dev->transport_packet_magic_header = strdup(value); dev->flags |= WGDEVICE_HAS_H4; } else if (!peer && !strcmp(key, "i1")) { dev->i1 = strdup(value); diff --git a/src/ipc-windows.h b/src/ipc-windows.h index 3756a52..cddadd4 100644 --- a/src/ipc-windows.h +++ b/src/ipc-windows.h @@ -292,19 +292,27 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) dev->flags |= WGDEVICE_HAS_S4; } if (wg_iface->Flags & WG_IOCTL_INTERFACE_H1) { - dev->init_packet_magic_header = wg_iface->InitPacketMagicHeader; + const size_t init_size = strlen((char*)wg_iface->InitPacketMagicHeader) + 1; + dev->init_packet_magic_header = (char*)malloc(init_size); + memcpy(dev->init_packet_magic_header, wg_iface->InitPacketMagicHeader, init_size); dev->flags |= WGDEVICE_HAS_H1; } if (wg_iface->Flags & WG_IOCTL_INTERFACE_H2) { - dev->response_packet_magic_header = wg_iface->ResponsePacketMagicHeader; + const size_t response_size = strlen((char*)wg_iface->ResponsePacketMagicHeader) + 1; + dev->response_packet_magic_header = (char*)malloc(response_size); + memcpy(dev->response_packet_magic_header, wg_iface->ResponsePacketMagicHeader, response_size); dev->flags |= WGDEVICE_HAS_H2; } if (wg_iface->Flags & WG_IOCTL_INTERFACE_H3) { - dev->underload_packet_magic_header = wg_iface->UnderloadPacketMagicHeader; + const size_t underload_size = strlen((char*)wg_iface->UnderloadPacketMagicHeader) + 1; + dev->underload_packet_magic_header = (char*)malloc(underload_size); + memcpy(dev->underload_packet_magic_header, wg_iface->UnderloadPacketMagicHeader, underload_size); dev->flags |= WGDEVICE_HAS_H3; } if (wg_iface->Flags & WG_IOCTL_INTERFACE_H4) { - dev->transport_packet_magic_header = wg_iface->TransportPacketMagicHeader; + const size_t transport_size = strlen((char*)wg_iface->TransportPacketMagicHeader) + 1; + dev->transport_packet_magic_header = (char*)malloc(transport_size); + memcpy(dev->transport_packet_magic_header, wg_iface->TransportPacketMagicHeader, transport_size); dev->flags |= WGDEVICE_HAS_H4; } if (wg_iface->Flags & WG_IOCTL_INTERFACE_I1) { @@ -516,22 +524,30 @@ static int kernel_set_device(struct wgdevice *dev) } if (dev->flags & WGDEVICE_HAS_H1) { - wg_iface->InitPacketMagicHeader = dev->init_packet_magic_header; + const size_t init_size = strlen(dev->init_packet_magic_header) + 1; + wg_iface->InitPacketMagicHeader = (char*)init_size; + memcpy(wg_iface->InitPacketMagicHeader, dev->init_packet_magic_header, init_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H1; } if (dev->flags & WGDEVICE_HAS_H2) { - wg_iface->ResponsePacketMagicHeader = dev->response_packet_magic_header; + const size_t response_size = strlen(dev->response_packet_magic_header) + 1; + wg_iface->ResponsePacketMagicHeader = (char*)response_size; + memcpy(wg_iface->ResponsePacketMagicHeader, dev->response_packet_magic_header, response_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H2; } if (dev->flags & WGDEVICE_HAS_H3) { - wg_iface->UnderloadPacketMagicHeader = dev->underload_packet_magic_header; + const size_t underload_size = strlen(dev->underload_packet_magic_header) + 1; + wg_iface->UnderloadPacketMagicHeader = (char*)underload_size; + memcpy(wg_iface->UnderloadPacketMagicHeader, dev->underload_packet_magic_header, underload_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H3; } if (dev->flags & WGDEVICE_HAS_H4) { - wg_iface->TransportPacketMagicHeader = dev->transport_packet_magic_header; + const size_t transport_size = strlen(dev->transport_packet_magic_header) + 1; + wg_iface->TransportPacketMagicHeader = (char*)transport_size; + memcpy(wg_iface->TransportPacketMagicHeader, dev->transport_packet_magic_header, transport_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H4; } diff --git a/src/show.c b/src/show.c index 93e1b03..dbecafb 100644 --- a/src/show.c +++ b/src/show.c @@ -235,13 +235,13 @@ static void pretty_print(struct wgdevice *device) if (device->transport_packet_junk_size) terminal_printf(" " TERMINAL_BOLD "s4" TERMINAL_RESET ": %u\n", device->transport_packet_junk_size); if (device->init_packet_magic_header) - terminal_printf(" " TERMINAL_BOLD "h1" TERMINAL_RESET ": %u\n", device->init_packet_magic_header); + terminal_printf(" " TERMINAL_BOLD "h1" TERMINAL_RESET ": %s\n", device->init_packet_magic_header); if (device->response_packet_magic_header) - terminal_printf(" " TERMINAL_BOLD "h2" TERMINAL_RESET ": %u\n", device->response_packet_magic_header); + terminal_printf(" " TERMINAL_BOLD "h2" TERMINAL_RESET ": %s\n", device->response_packet_magic_header); if (device->underload_packet_magic_header) - terminal_printf(" " TERMINAL_BOLD "h3" TERMINAL_RESET ": %u\n", device->underload_packet_magic_header); + terminal_printf(" " TERMINAL_BOLD "h3" TERMINAL_RESET ": %s\n", device->underload_packet_magic_header); if (device->transport_packet_magic_header) - terminal_printf(" " TERMINAL_BOLD "h4" TERMINAL_RESET ": %u\n", device->transport_packet_magic_header); + terminal_printf(" " TERMINAL_BOLD "h4" TERMINAL_RESET ": %s\n", device->transport_packet_magic_header); if (device->i1) terminal_printf(" " TERMINAL_BOLD "i1" TERMINAL_RESET ": %s\n", device->i1); if (device->i2) @@ -308,10 +308,10 @@ static void dump_print(struct wgdevice *device, bool with_interface) printf("%u\t", device->response_packet_junk_size); printf("%u\t", device->cookie_reply_packet_junk_size); printf("%u\t", device->transport_packet_junk_size); - printf("%u\t", device->init_packet_magic_header); - printf("%u\t", device->response_packet_magic_header); - printf("%u\t", device->underload_packet_magic_header); - printf("%u\t", device->transport_packet_magic_header); + printf("%s\t", device->init_packet_magic_header); + printf("%s\t", device->response_packet_magic_header); + printf("%s\t", device->underload_packet_magic_header); + printf("%s\t", device->transport_packet_magic_header); printf("%s\t", device->i1); printf("%s\t", device->i2); printf("%s\t", device->i3); @@ -404,19 +404,19 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int } else if(!strcmp(param, "h1")) { if (with_interface) printf("%s\t", device->name); - printf("%u\n", device->init_packet_magic_header); + printf("%s\n", device->init_packet_magic_header); } else if(!strcmp(param, "h2")) { if (with_interface) printf("%s\t", device->name); - printf("%u\n", device->response_packet_magic_header); + printf("%s\n", device->response_packet_magic_header); } else if(!strcmp(param, "h3")) { if (with_interface) printf("%s\t", device->name); - printf("%u\n", device->underload_packet_magic_header); + printf("%s\n", device->underload_packet_magic_header); } else if(!strcmp(param, "h4")) { if (with_interface) printf("%s\t", device->name); - printf("%u\n", device->transport_packet_magic_header); + printf("%s\n", device->transport_packet_magic_header); } else if(!strcmp(param, "i1")) { if (with_interface) printf("%s\t", device->name); diff --git a/src/showconf.c b/src/showconf.c index b049f6e..11952cb 100644 --- a/src/showconf.c +++ b/src/showconf.c @@ -61,13 +61,13 @@ int showconf_main(int argc, const char *argv[]) if (device->flags & WGDEVICE_HAS_S4) printf("S4 = %u\n", device->transport_packet_junk_size); if (device->flags & WGDEVICE_HAS_H1) - printf("H1 = %u\n", device->init_packet_magic_header); + printf("H1 = %s\n", device->init_packet_magic_header); if (device->flags & WGDEVICE_HAS_H2) - printf("H2 = %u\n", device->response_packet_magic_header); + printf("H2 = %s\n", device->response_packet_magic_header); if (device->flags & WGDEVICE_HAS_H3) - printf("H3 = %u\n", device->underload_packet_magic_header); + printf("H3 = %s\n", device->underload_packet_magic_header); if (device->flags & WGDEVICE_HAS_H4) - printf("H4 = %u\n", device->transport_packet_magic_header); + printf("H4 = %s\n", device->transport_packet_magic_header); if (device->flags & WGDEVICE_HAS_I1) printf("I1 = %s\n", device->i1); if (device->flags & WGDEVICE_HAS_I2) diff --git a/src/uapi/openbsd/net/if_wg.h b/src/uapi/openbsd/net/if_wg.h index 1f30572..5a8c94d 100644 --- a/src/uapi/openbsd/net/if_wg.h +++ b/src/uapi/openbsd/net/if_wg.h @@ -109,10 +109,10 @@ struct wg_interface_io { uint16_t i_response_packet_junk_size; uint16_t i_cookie_reply_packet_junk_size; uint16_t i_transport_packet_junk_size; - uint32_t i_init_packet_magic_header; - uint32_t i_response_packet_magic_header; - uint32_t i_underload_packet_magic_header; - uint32_t i_transport_packet_magic_header; + uint8_t* i_init_packet_magic_header; + uint8_t* i_response_packet_magic_header; + uint8_t* i_underload_packet_magic_header; + uint8_t* i_transport_packet_magic_header; uint8_t* i_i1; uint8_t* i_i2; diff --git a/src/uapi/windows/wireguard.h b/src/uapi/windows/wireguard.h index a076b46..0ddcde6 100644 --- a/src/uapi/windows/wireguard.h +++ b/src/uapi/windows/wireguard.h @@ -94,10 +94,10 @@ typedef struct _WG_IOCTL_INTERFACE USHORT ResponsePacketJunkSize; USHORT CookieReplyPacketJunkSize; USHORT TransportPacketJunkSize; - ULONG InitPacketMagicHeader; - ULONG ResponsePacketMagicHeader; - ULONG UnderloadPacketMagicHeader; - ULONG TransportPacketMagicHeader; + UCHAR* InitPacketMagicHeader; + UCHAR* ResponsePacketMagicHeader; + UCHAR* UnderloadPacketMagicHeader; + UCHAR* TransportPacketMagicHeader; UCHAR* I1; UCHAR* I2; diff --git a/src/wg-quick/android.c b/src/wg-quick/android.c index dd3a340..e2d9f67 100644 --- a/src/wg-quick/android.c +++ b/src/wg-quick/android.c @@ -41,8 +41,7 @@ static bool is_exiting = false; static bool binder_available = false; static unsigned int sdk_version; -static bool is_asecurity_on = false; -static bool is_special_handshake_on = false; +static bool is_awg_on = false; static void *xmalloc(size_t size) { @@ -634,7 +633,7 @@ static void auto_su(int argc, char *argv[]) static void add_if(const char *iface) { - if (is_asecurity_on || is_special_handshake_on) + if (is_awg_on) cmd("amneziawg-go %s", iface); else cmd("ip link add %s type amneziawg", iface); @@ -1262,45 +1261,45 @@ static void parse_options(char **iface, char **config, unsigned int *mtu, char * *mtu = atoi(clean + 4); continue; } else if (!strncasecmp(clean, "Jc=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "Jmin=", 5) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "Jmax=", 5) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "S1=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "S2=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "S3=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "S4=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "H1=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "H2=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "H3=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "H4=", 3) && j > 4) { - is_asecurity_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "I1=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "I2=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "I3=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "I4=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "I5=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "J1=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "J2=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "J3=", 3) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } else if (!strncasecmp(clean, "Itime=", 6) && j > 4) { - is_special_handshake_on = true; + is_awg_on = true; } } *config = concat_and_free(*config, "", line); diff --git a/src/wg-quick/freebsd.bash b/src/wg-quick/freebsd.bash index 8cb065d..60e7ca6 100755 --- a/src/wg-quick/freebsd.bash +++ b/src/wg-quick/freebsd.bash @@ -28,7 +28,7 @@ CONFIG_FILE="" PROGRAM="${0##*/}" ARGS=( "$@" ) -IS_ASESCURITY_ON=0 +IS_AWG_ON=0 cmd() { echo "[#] $*" >&3 @@ -104,10 +104,21 @@ parse_options() { Jmax);& S1);& S2);& + S3);& + S4);& H1);& H2);& H3);& - H4) IS_ASESCURITY_ON=1;; + H4);& + I1);& + i2);& + I3);& + I4);& + I5);& + J1);& + J2);& + J3);& + Itime) IS_AWG_ON=1;; esac fi WG_CONFIG+="$line"$'\n' @@ -130,7 +141,7 @@ auto_su() { add_if() { local ret rc local cmd="ifconfig wg create name "$INTERFACE"" - if [[ $IS_ASESCURITY_ON == 1 ]]; then + if [[ $IS_AWG_ON == 1 ]]; then cmd="amneziawg-go "$INTERFACE""; fi if ret="$(cmd $cmd 2>&1 >/dev/null)"; then @@ -501,4 +512,4 @@ else exit 1 fi -exit 0 \ No newline at end of file +exit 0 diff --git a/src/wg-quick/openbsd.bash b/src/wg-quick/openbsd.bash index 502cc9a..210570b 100755 --- a/src/wg-quick/openbsd.bash +++ b/src/wg-quick/openbsd.bash @@ -27,7 +27,7 @@ SAVE_CONFIG=0 CONFIG_FILE="" PROGRAM="${0##*/}" ARGS=( "$@" ) -IS_ASESCURITY_ON=0 +IS_AWG_ON=0 cmd() { echo "[#] $*" >&3 @@ -75,10 +75,21 @@ parse_options() { Jmax);& S1);& S2);& + S3);& + S4);& H1);& H2);& H3);& - H4) IS_ASESCURITY_ON=1;; + H4);& + I1);& + i2);& + I3);& + I4);& + I5);& + J1);& + J2);& + J3);& + Itime) IS_AWG_ON=1;; esac fi WG_CONFIG+="$line"$'\n' @@ -118,7 +129,7 @@ add_if() { while true; do local -A existing_ifs="( $(wg show interfaces | sed 's/\([^ ]*\)/[\1]=1/g') )" local index ret - if [[ $IS_ASESCURITY_ON == 1 ]]; then + if [[ $IS_AWG_ON == 1 ]]; then cmd "amneziawg-go "$INTERFACE""; return $? else @@ -495,4 +506,4 @@ else exit 1 fi -exit 0 \ No newline at end of file +exit 0 From 430e39aaf9008840b016d8be1204aede89749e01 Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Fri, 18 Jul 2025 05:09:12 +0200 Subject: [PATCH 5/8] chore: rename advanced security to awg --- contrib/embeddable-wg-library/wireguard.c | 6 +-- contrib/peer-approver/approve.sh | 5 +- contrib/peer-approver/notification-listener.c | 25 ++++------ src/config.c | 22 +++------ src/containers.h | 10 ++-- src/ipc-freebsd.h | 24 +++++----- src/ipc-linux.h | 47 +++++-------------- src/ipc-uapi.h | 7 +-- src/showconf.c | 7 +-- src/uapi/linux/linux/wireguard.h | 16 ++----- 10 files changed, 54 insertions(+), 115 deletions(-) diff --git a/contrib/embeddable-wg-library/wireguard.c b/contrib/embeddable-wg-library/wireguard.c index 26de0e9..802989d 100644 --- a/contrib/embeddable-wg-library/wireguard.c +++ b/contrib/embeddable-wg-library/wireguard.c @@ -74,8 +74,7 @@ enum wgdevice_attribute { enum wgpeer_flag { WGPEER_F_REMOVE_ME = 1U << 0, WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1, - WGPEER_F_HAS_ADVANCED_SECURITY = 1U << 3, - WGPEER_F_HAS_SPECIAL_HANDSHAKE = 1U << 4 + WGPEER_F_HAS_AWG = 1U << 3 }; enum wgpeer_attribute { WGPEER_A_UNSPEC, @@ -89,8 +88,7 @@ enum wgpeer_attribute { WGPEER_A_TX_BYTES, WGPEER_A_ALLOWEDIPS, WGPEER_A_PROTOCOL_VERSION, - WGPEER_A_ADVANCED_SECURITY, - WGPEER_A_SPECIAL_HANDSHAKE, + WGPEER_A_AWG, __WGPEER_A_LAST }; diff --git a/contrib/peer-approver/approve.sh b/contrib/peer-approver/approve.sh index e711a6c..e160856 100755 --- a/contrib/peer-approver/approve.sh +++ b/contrib/peer-approver/approve.sh @@ -4,8 +4,7 @@ ACCOUNTS_FILE=$1 INTERFACE_NAME=$2 PUBLIC_KEY=$3 ENDPOINT=$4 -ADVANCED_SECURITY=$5 -SPECIAL_HANDSHAKE=$6 +AWG=$5 ACCOUNT_STR=`grep "${PUBLIC_KEY}" "${ACCOUNTS_FILE}"` @@ -20,7 +19,7 @@ PSK=$(echo ${ACCOUNT[2]}|tr -d '"') PSK_FILE=$(tempfile) echo "${PSK}" > "${PSK_FILE}" -awg set "${INTERFACE_NAME}" peer "${PUBLIC_KEY}" allowed-ips "${ALLOWED_IPS}" endpoint "${ENDPOINT}" allowed-ips "${ALLOWED_IPS}" preshared-key "${PSK_FILE}" advanced-security "${ADVANCED_SECURITY}" special-handshake "${SPECIAL_HANDSHAKE}" +awg set "${INTERFACE_NAME}" peer "${PUBLIC_KEY}" allowed-ips "${ALLOWED_IPS}" endpoint "${ENDPOINT}" allowed-ips "${ALLOWED_IPS}" preshared-key "${PSK_FILE}" awg "${AWG}" EXIT_CODE=$? rm -f "{$PSK_FILE}" diff --git a/contrib/peer-approver/notification-listener.c b/contrib/peer-approver/notification-listener.c index 0057e71..5076975 100644 --- a/contrib/peer-approver/notification-listener.c +++ b/contrib/peer-approver/notification-listener.c @@ -116,19 +116,18 @@ static int get_endpoint(struct nlattr *peer[], char **endpoint_ip) return 0; } -static int run_callback(char *ifname, char *pubkey, char *endpoint_ip, bool advanced_security, bool special_handshake) +static int run_callback(char *ifname, char *pubkey, char *endpoint_ip, bool is_awg) { char** new_argv = malloc((cb_argc + 2) * sizeof *new_argv); new_argv[0] = cb_argv[1]; - for (int i = 2; i < cb_argc - 4; i++) { + for (int i = 2; i < cb_argc - 3; i++) { new_argv[i - 1] = cb_argv[i]; } - new_argv[cb_argc - 5] = ifname; - new_argv[cb_argc - 4] = pubkey; - new_argv[cb_argc - 3] = endpoint_ip; - new_argv[cb_argc - 2] = (advanced_security ? "on\0" : "off\0"); - new_argv[cb_argc - 1] = (special_handshake ? "on\0" : "off\0"); + new_argv[cb_argc - 4] = ifname; + new_argv[cb_argc - 3] = pubkey; + new_argv[cb_argc - 2] = endpoint_ip; + new_argv[cb_argc - 1] = (is_awg ? "on\0" : "off\0"); new_argv[cb_argc] = NULL; int child_pid = fork(), ret; @@ -156,8 +155,7 @@ static int netlink_callback(struct nl_msg *msg, void *arg) nla_parse(tb, WGDEVICE_A_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL); char *ifname, *pubkey, *endpoint_ip; - bool advanced_security = false; - bool special_handshake = false; + bool is_awg = false; int cb_ret; switch (gnlh->cmd) { @@ -178,13 +176,10 @@ static int netlink_callback(struct nl_msg *msg, void *arg) prerr("invalid endpoint!\n"); return NL_SKIP; } - if (nla_get_flag(peer[WGPEER_A_ADVANCED_SECURITY])) { - advanced_security = true; + if (nla_get_flag(peer[WGPEER_A_AWG])) { + is_awg = true; } - if (nla_get_flag(peer[WGPEER_A_SPECIAL_HANDSHAKE])) { - special_handshake = true; - } - if (cb_ret = run_callback(ifname, pubkey, endpoint_ip, advanced_security, special_handshake)) { + if (cb_ret = run_callback(ifname, pubkey, endpoint_ip, is_awg)) { prerr("failed to execute callback script: %d!\n", cb_ret); return NL_SKIP; } diff --git a/src/config.c b/src/config.c index 6aa31b0..80d098d 100644 --- a/src/config.c +++ b/src/config.c @@ -425,8 +425,8 @@ static inline bool parse_awg_string(char **device_value, const char *name, const return true; } - if (len >= MAX_AWG_JUNK_LEN) { - fprintf(stderr, "Unable to process string for: %s; longer than: %d\n", name, MAX_AWG_JUNK_LEN); + if (len >= MAX_AWG_STRING_LEN) { + fprintf(stderr, "Unable to process string for: %s; longer than: %d\n", name, MAX_AWG_STRING_LEN); return false; } *device_value = strdup(value); @@ -645,13 +645,9 @@ static bool process_line(struct config_ctx *ctx, const char *line) 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); + ret = parse_bool(&ctx->last_peer->awg, "AdvancedSecurity", value); if (ret) - ctx->last_peer->flags |= WGPEER_HAS_ADVANCED_SECURITY; - } else if (key_match("SpecialHandshake")) { - ret = parse_bool(&ctx->last_peer->special_handshake, "SpecialHandshake", value); - if (ret) - ctx->last_peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; + ctx->last_peer->flags |= WGPEER_HAS_AWG; } else goto error; } else @@ -1017,15 +1013,9 @@ struct wgdevice *config_read_cmd(const char *argv[], int argc) argv += 2; argc -= 2; } else if (!strcmp(argv[0], "advanced-security") && argc >= 2 && peer) { - if (!parse_bool(&peer->advanced_security, "AdvancedSecurity", argv[1])) + if (!parse_bool(&peer->awg, "AdvancedSecurity", argv[1])) goto error; - peer->flags |= WGPEER_HAS_ADVANCED_SECURITY; - argv += 2; - argc -= 2; - } else if (!strcmp(argv[0], "special-handshake") && argc >= 2 && peer) { - if (!parse_bool(&peer->special_handshake, "SpecialHandshake", argv[1])) - goto error; - peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; + peer->flags |= WGPEER_HAS_AWG; argv += 2; argc -= 2; } else { diff --git a/src/containers.h b/src/containers.h index 21f22a0..fa722bc 100644 --- a/src/containers.h +++ b/src/containers.h @@ -23,8 +23,8 @@ #define WG_KEY_LEN 32 #endif -#ifndef MAX_AWG_JUNK_LEN -#define MAX_AWG_JUNK_LEN 5 * 1024 +#ifndef MAX_AWG_STRING_LEN +#define MAX_AWG_STRING_LEN 5 * 1024 #endif /* Cross platform __kernel_timespec */ @@ -49,8 +49,7 @@ enum { WGPEER_HAS_PUBLIC_KEY = 1U << 2, WGPEER_HAS_PRESHARED_KEY = 1U << 3, WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4, - WGPEER_HAS_ADVANCED_SECURITY = 1U << 5, - WGPEER_HAS_SPECIAL_HANDSHAKE = 1U << 6 + WGPEER_HAS_AWG = 1U << 5 }; struct wgpeer { @@ -69,8 +68,7 @@ struct wgpeer { uint64_t rx_bytes, tx_bytes; uint16_t persistent_keepalive_interval; - bool advanced_security; - bool special_handshake; + bool awg; struct wgallowedip *first_allowedip, *last_allowedip; struct wgpeer *next_peer; diff --git a/src/ipc-freebsd.h b/src/ipc-freebsd.h index 5773937..170d74c 100644 --- a/src/ipc-freebsd.h +++ b/src/ipc-freebsd.h @@ -142,7 +142,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) } if (nvlist_exists_number(nvl_device, "h1")) { binary = nvlist_get_binary(nvl_device, "h1", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->init_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H1; @@ -150,7 +150,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) } if (nvlist_exists_number(nvl_device, "h2")) { binary = nvlist_get_binary(nvl_device, "h2", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->response_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H2; @@ -158,7 +158,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) } if (nvlist_exists_number(nvl_device, "h3")) { binary = nvlist_get_binary(nvl_device, "h3", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->underload_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H3; @@ -166,7 +166,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) } if (nvlist_exists_number(nvl_device, "h4")) { binary = nvlist_get_binary(nvl_device, "h4", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->transport_packet_magic_header = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_H4; @@ -175,7 +175,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "i1")) { binary = nvlist_get_binary(nvl_device, "i1", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->i1 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_I1; @@ -184,7 +184,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "i2")) { binary = nvlist_get_binary(nvl_device, "i2", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->i2 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_I2; @@ -193,7 +193,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "i3")) { binary = nvlist_get_binary(nvl_device, "i3", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->i3 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_I3; @@ -202,7 +202,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "i4")) { binary = nvlist_get_binary(nvl_device, "i4", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->i4 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_I4; @@ -211,7 +211,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "i5")) { binary = nvlist_get_binary(nvl_device, "i5", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->i5 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_I5; @@ -220,7 +220,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "j1")) { binary = nvlist_get_binary(nvl_device, "j1", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->j1 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_J1; @@ -229,7 +229,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "j2")) { binary = nvlist_get_binary(nvl_device, "j2", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->j2 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_J2; @@ -238,7 +238,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (nvlist_exists_binary(nvl_device, "j3")) { binary = nvlist_get_binary(nvl_device, "j3", &size); - if (binary && size < MAX_AWG_JUNK_LEN) + if (binary && size < MAX_AWG_STRING_LEN) { dev->j3 = strdup((const char*)binary); dev->flags |= WGDEVICE_HAS_J3; diff --git a/src/ipc-linux.h b/src/ipc-linux.h index 09bf48a..77542c1 100644 --- a/src/ipc-linux.h +++ b/src/ipc-linux.h @@ -243,17 +243,10 @@ again: 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 (peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE) - { - if (peer->special_handshake) - mnl_attr_put_check( - nlh, SOCKET_BUFFER_SIZE, WGPEER_A_SPECIAL_HANDSHAKE, 0, NULL); - flags |= WGPEER_F_HAS_SPECIAL_HANDSHAKE; + if (peer->flags & WGPEER_HAS_AWG) { + if (peer->awg) + mnl_attr_put_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_AWG, 0, NULL); + flags |= WGPEER_F_HAS_AWG; } if (flags) { if (!mnl_attr_put_u32_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_FLAGS, flags)) @@ -427,36 +420,18 @@ static int parse_peer(const struct nlattr *attr, void *data) 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; - } - if ( - flags & WGPEER_F_HAS_SPECIAL_HANDSHAKE && - !(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)) - { - peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; - peer->special_handshake = false; + if (flags & WGPEER_F_HAS_AWG && !(peer->flags & WGPEER_HAS_AWG)) { + peer->flags |= WGPEER_HAS_AWG; + peer->awg = false; } } break; - case WGPEER_A_ADVANCED_SECURITY: + case WGPEER_A_AWG: if (!mnl_attr_validate(attr, MNL_TYPE_FLAG)) { - peer->advanced_security = true; + peer->awg = true; - if (!(peer->flags & WGPEER_HAS_ADVANCED_SECURITY)) { - peer->flags |= WGPEER_HAS_ADVANCED_SECURITY; - } - } - break; - case WGPEER_A_SPECIAL_HANDSHAKE: - if (!mnl_attr_validate(attr, MNL_TYPE_FLAG)) - { - peer->special_handshake = true; - - if (!(peer->flags & WGPEER_HAS_SPECIAL_HANDSHAKE)) - { - peer->flags |= WGPEER_HAS_SPECIAL_HANDSHAKE; + if (!(peer->flags & WGPEER_HAS_AWG)) { + peer->flags |= WGPEER_HAS_AWG; } } break; diff --git a/src/ipc-uapi.h b/src/ipc-uapi.h index 74640a6..b6cfafb 100644 --- a/src/ipc-uapi.h +++ b/src/ipc-uapi.h @@ -96,12 +96,7 @@ 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_HAS_SPECIAL_HANDSHAKE) - { + if (peer->flags & WGPEER_HAS_AWG) { ret = -EINVAL; goto out; } diff --git a/src/showconf.c b/src/showconf.c index 11952cb..81d5354 100644 --- a/src/showconf.c +++ b/src/showconf.c @@ -95,11 +95,8 @@ 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->flags & WGPEER_HAS_SPECIAL_HANDSHAKE) { - printf("SpecialHandshake = %s\n", peer->special_handshake ? "on" : "off"); + if (peer->flags & WGPEER_HAS_AWG) { + printf("AdvancedSecurity = %s\n", peer->awg ? "on" : "off"); } if (peer->first_allowedip) printf("AllowedIPs = "); diff --git a/src/uapi/linux/linux/wireguard.h b/src/uapi/linux/linux/wireguard.h index 4438e83..927a1ea 100644 --- a/src/uapi/linux/linux/wireguard.h +++ b/src/uapi/linux/linux/wireguard.h @@ -111,10 +111,7 @@ * 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. - * WGPEER_A_SPECIAL_HANDSHAKE: flag indicating that special handshake + * WGPEER_A_AWG: flag indicating that advanced security * techniques provided by AmneziaWG should * be used. * 0: NLA_NESTED @@ -147,10 +144,7 @@ * WGDEVICE_A_PEER: NLA_NESTED * WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN * WGPEER_A_ENDPOINT: NLA_MIN_LEN(struct sockaddr), struct sockaddr_in or struct sockaddr_in6 - * WGPEER_A_ADVANCED_SECURITY: flag indicating that advanced security - * techniques provided by AmneziaWG should - * be used. - * WGPEER_A_SPECIAL_HANDSHAKE: flag indicating that special handshake + * WGPEER_A_AWG: flag indicating that advanced security * techniques provided by AmneziaWG should * be used. * @@ -217,8 +211,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_HAS_SPECIAL_HANDSHAKE = 1U << 4, + WGPEER_F_HAS_AWG = 1U << 3, __WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS | WGPEER_F_UPDATE_ONLY }; @@ -234,8 +227,7 @@ enum wgpeer_attribute { WGPEER_A_TX_BYTES, WGPEER_A_ALLOWEDIPS, WGPEER_A_PROTOCOL_VERSION, - WGPEER_A_ADVANCED_SECURITY, - WGPEER_A_SPECIAL_HANDSHAKE, + WGPEER_A_AWG, __WGPEER_A_LAST }; #define WGPEER_A_MAX (__WGPEER_A_LAST - 1) From 3a610feb96c7eb38a0806de08922edbaf4db9b1e Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Tue, 22 Jul 2025 06:25:05 +0200 Subject: [PATCH 6/8] fix: awg memory management --- src/containers.h | 15 +++++++++++++++ src/ipc-freebsd.h | 8 ++++---- src/ipc-linux.h | 8 ++++---- src/ipc-openbsd.h | 26 ++++++++++++++++++++++++++ src/ipc-windows.h | 22 ++++++++++++++++++---- 5 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/containers.h b/src/containers.h index fa722bc..b72e0f0 100644 --- a/src/containers.h +++ b/src/containers.h @@ -150,6 +150,21 @@ static inline void free_wgdevice(struct wgdevice *dev) free(allowedip); free(peer); } + + + free(dev->init_packet_magic_header); + free(dev->response_packet_magic_header); + free(dev->underload_packet_magic_header); + free(dev->transport_packet_magic_header); + free(dev->i1); + free(dev->i2); + free(dev->i3); + free(dev->i4); + free(dev->i5); + free(dev->j1); + free(dev->j2); + free(dev->j3); + free(dev); } diff --git a/src/ipc-freebsd.h b/src/ipc-freebsd.h index 170d74c..52f9f34 100644 --- a/src/ipc-freebsd.h +++ b/src/ipc-freebsd.h @@ -140,7 +140,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) dev->flags |= WGDEVICE_HAS_S4; } } - if (nvlist_exists_number(nvl_device, "h1")) { + if (nvlist_exists_binary(nvl_device, "h1")) { binary = nvlist_get_binary(nvl_device, "h1", &size); if (binary && size < MAX_AWG_STRING_LEN) { @@ -148,7 +148,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) dev->flags |= WGDEVICE_HAS_H1; } } - if (nvlist_exists_number(nvl_device, "h2")) { + if (nvlist_exists_binary(nvl_device, "h2")) { binary = nvlist_get_binary(nvl_device, "h2", &size); if (binary && size < MAX_AWG_STRING_LEN) { @@ -156,7 +156,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) dev->flags |= WGDEVICE_HAS_H2; } } - if (nvlist_exists_number(nvl_device, "h3")) { + if (nvlist_exists_binary(nvl_device, "h3")) { binary = nvlist_get_binary(nvl_device, "h3", &size); if (binary && size < MAX_AWG_STRING_LEN) { @@ -164,7 +164,7 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) dev->flags |= WGDEVICE_HAS_H3; } } - if (nvlist_exists_number(nvl_device, "h4")) { + if (nvlist_exists_binary(nvl_device, "h4")) { binary = nvlist_get_binary(nvl_device, "h4", &size); if (binary && size < MAX_AWG_STRING_LEN) { diff --git a/src/ipc-linux.h b/src/ipc-linux.h index 77542c1..8c2e682 100644 --- a/src/ipc-linux.h +++ b/src/ipc-linux.h @@ -548,25 +548,25 @@ static int parse_device(const struct nlattr *attr, void *data) } break; case WGDEVICE_A_H1: - if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->init_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H1; } break; case WGDEVICE_A_H2: - if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->response_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H2; } break; case WGDEVICE_A_H3: - if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->underload_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H3; } break; case WGDEVICE_A_H4: - if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->transport_packet_magic_header = strdup(mnl_attr_get_str(attr)); device->flags |= WGDEVICE_HAS_H4; } diff --git a/src/ipc-openbsd.h b/src/ipc-openbsd.h index 383de9b..231ff77 100644 --- a/src/ipc-openbsd.h +++ b/src/ipc-openbsd.h @@ -495,6 +495,32 @@ static int kernel_set_device(struct wgdevice *dev) out: ret = -errno; + if (wgdata.wgd_interface) { + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H1) + free(wg_iface->i_init_packet_magic_header); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H2) + free(wg_iface->i_response_packet_magic_header); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H3) + free(wg_iface->i_underload_packet_magic_header); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H4) + free(wg_iface->i_transport_packet_magic_header); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I1) + free(wg_iface->i_i1); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I2) + free(wg_iface->i_i2); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I3) + free(wg_iface->i_i3); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I4) + free(wg_iface->i_i4); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I5) + free(wg_iface->i_i5); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J1) + free(wg_iface->i_j1); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J2) + free(wg_iface->i_j2); + if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J3) + free(wg_iface->i_j3); + } free(wgdata.wgd_interface); return ret; } diff --git a/src/ipc-windows.h b/src/ipc-windows.h index cddadd4..c4da037 100644 --- a/src/ipc-windows.h +++ b/src/ipc-windows.h @@ -525,28 +525,28 @@ static int kernel_set_device(struct wgdevice *dev) if (dev->flags & WGDEVICE_HAS_H1) { const size_t init_size = strlen(dev->init_packet_magic_header) + 1; - wg_iface->InitPacketMagicHeader = (char*)init_size; + wg_iface->InitPacketMagicHeader = (UCHAR*)malloc(init_size); memcpy(wg_iface->InitPacketMagicHeader, dev->init_packet_magic_header, init_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H1; } if (dev->flags & WGDEVICE_HAS_H2) { const size_t response_size = strlen(dev->response_packet_magic_header) + 1; - wg_iface->ResponsePacketMagicHeader = (char*)response_size; + wg_iface->ResponsePacketMagicHeader = (UCHAR*)malloc(response_size); memcpy(wg_iface->ResponsePacketMagicHeader, dev->response_packet_magic_header, response_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H2; } if (dev->flags & WGDEVICE_HAS_H3) { const size_t underload_size = strlen(dev->underload_packet_magic_header) + 1; - wg_iface->UnderloadPacketMagicHeader = (char*)underload_size; + wg_iface->UnderloadPacketMagicHeader = (UCHAR*)malloc(underload_size); memcpy(wg_iface->UnderloadPacketMagicHeader, dev->underload_packet_magic_header, underload_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H3; } if (dev->flags & WGDEVICE_HAS_H4) { const size_t transport_size = strlen(dev->transport_packet_magic_header) + 1; - wg_iface->TransportPacketMagicHeader = (char*)transport_size; + wg_iface->TransportPacketMagicHeader = (UCHAR*)malloc(transport_size); memcpy(wg_iface->TransportPacketMagicHeader, dev->transport_packet_magic_header, transport_size); wg_iface->Flags |= WG_IOCTL_INTERFACE_H4; } @@ -672,6 +672,20 @@ static int kernel_set_device(struct wgdevice *dev) out: ret = -errno; + if (wg_iface) { + free(wg_iface->InitPacketMagicHeader); + free(wg_iface->ResponsePacketMagicHeader); + free(wg_iface->UnderloadPacketMagicHeader); + free(wg_iface->TransportPacketMagicHeader); + free(wg_iface->I1); + free(wg_iface->I2); + free(wg_iface->I3); + free(wg_iface->I4); + free(wg_iface->I5); + free(wg_iface->J1); + free(wg_iface->J2); + free(wg_iface->J3); + } free(wg_iface); CloseHandle(handle); return ret; From 110e1b1ee693dc9f565b8e7319084c6ed23b5d66 Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Tue, 22 Jul 2025 18:19:48 +0200 Subject: [PATCH 7/8] fix: NULL out empty string --- src/config.c | 2 +- src/containers.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index 80d098d..b8e56da 100644 --- a/src/config.c +++ b/src/config.c @@ -421,7 +421,7 @@ err: static inline bool parse_awg_string(char **device_value, const char *name, const char *value) { size_t len = strlen(value); if (!len) { - *device_value = ""; + *device_value = NULL; return true; } diff --git a/src/containers.h b/src/containers.h index b72e0f0..7ba9fac 100644 --- a/src/containers.h +++ b/src/containers.h @@ -151,7 +151,6 @@ static inline void free_wgdevice(struct wgdevice *dev) free(peer); } - free(dev->init_packet_magic_header); free(dev->response_packet_magic_header); free(dev->underload_packet_magic_header); From c5b17c2c9b4d61640968517dfd5bfcb2fe6c3ace Mon Sep 17 00:00:00 2001 From: Mark Puha Date: Tue, 22 Jul 2025 19:04:51 +0200 Subject: [PATCH 8/8] fix: copilot review --- contrib/json/wg-json | 8 +-- contrib/peer-approver/approve.sh | 2 +- src/config.c | 23 +++++---- src/containers.h | 24 ++++----- src/ipc-freebsd.h | 58 +++++++++++++++++++-- src/ipc-linux.h | 87 +++++++++++++++++++++++++------- src/ipc-openbsd.h | 74 ++++++++++++++++++++++++++- src/ipc-uapi.h | 84 ++++++++++++++++++++++++------ src/ipc-windows.h | 36 ++++++++----- src/show.c | 76 ++++++++++++++++------------ src/uapi/windows/wireguard.h | 24 ++++----- src/wg-quick/freebsd.bash | 2 +- src/wg-quick/openbsd.bash | 2 +- 13 files changed, 376 insertions(+), 124 deletions(-) diff --git a/contrib/json/wg-json b/contrib/json/wg-json index 3778b1d..bd15f03 100755 --- a/contrib/json/wg-json +++ b/contrib/json/wg-json @@ -24,10 +24,10 @@ while read -r -d $'\t' device; do [[ $s2 == "0" ]] || { printf '%s\t\t"s2": %u' "$delim" $(( $s2 )); delim=$',\n'; } [[ $s3 == "0" ]] || { printf '%s\t\t"s3": %u' "$delim" $(( $s3 )); delim=$',\n'; } [[ $s4 == "0" ]] || { printf '%s\t\t"s4": %u' "$delim" $(( $s4 )); delim=$',\n'; } - [[ $h1 == "1" ]] || { printf '%s\t\t"h1": %s' "$delim" $(( $h1 )); delim=$',\n'; } - [[ $h2 == "2" ]] || { printf '%s\t\t"h2": %s' "$delim" $(( $h2 )); delim=$',\n'; } - [[ $h3 == "3" ]] || { printf '%s\t\t"h3": %s' "$delim" $(( $h3 )); delim=$',\n'; } - [[ $h4 == "4" ]] || { printf '%s\t\t"h4": %s' "$delim" $(( $h4 )); delim=$',\n'; } + [[ $h1 == "1" ]] || { printf '%s\t\t"h1": "%s"' "$delim" "$h1"; delim=$',\n'; } + [[ $h2 == "2" ]] || { printf '%s\t\t"h2": "%s"' "$delim" "$h2"; delim=$',\n'; } + [[ $h3 == "3" ]] || { printf '%s\t\t"h3": "%s"' "$delim" "$h3"; delim=$',\n'; } + [[ $h4 == "4" ]] || { printf '%s\t\t"h4": "%s"' "$delim" "$h4"; delim=$',\n'; } [[ $i1 == "(none)" ]] || { printf '%s\t\t"i1": "%s"' "$delim" "$i1"; delim=$',\n'; } [[ $i2 == "(none)" ]] || { printf '%s\t\t"i2": "%s"' "$delim" "$i2"; delim=$',\n'; } [[ $i3 == "(none)" ]] || { printf '%s\t\t"i3": "%s"' "$delim" "$i3"; delim=$',\n'; } diff --git a/contrib/peer-approver/approve.sh b/contrib/peer-approver/approve.sh index e160856..09ae90d 100755 --- a/contrib/peer-approver/approve.sh +++ b/contrib/peer-approver/approve.sh @@ -19,7 +19,7 @@ PSK=$(echo ${ACCOUNT[2]}|tr -d '"') PSK_FILE=$(tempfile) echo "${PSK}" > "${PSK_FILE}" -awg set "${INTERFACE_NAME}" peer "${PUBLIC_KEY}" allowed-ips "${ALLOWED_IPS}" endpoint "${ENDPOINT}" allowed-ips "${ALLOWED_IPS}" preshared-key "${PSK_FILE}" awg "${AWG}" +awg set "${INTERFACE_NAME}" peer "${PUBLIC_KEY}" allowed-ips "${ALLOWED_IPS}" endpoint "${ENDPOINT}" preshared-key "${PSK_FILE}" advanced-security "${AWG}" EXIT_CODE=$? rm -f "{$PSK_FILE}" diff --git a/src/config.c b/src/config.c index b8e56da..e02694f 100644 --- a/src/config.c +++ b/src/config.c @@ -22,7 +22,7 @@ #define COMMENT_CHAR '#' -// Keys that should return empty string instead of NULL when not found +// Keys that should be not stripped of whitespace static const char *awg_special_handshake_keys[] = { "I1", "I2", "I3", "I4", "I5", "J1", "J2", "J3", @@ -431,6 +431,11 @@ static inline bool parse_awg_string(char **device_value, const char *name, const } *device_value = strdup(value); + if (*device_value == NULL) { + perror("strdup"); + return false; + } + return true; } @@ -912,56 +917,56 @@ struct wgdevice *config_read_cmd(const char *argv[], int argc) device->flags |= WGDEVICE_HAS_I2; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "i3") && argc >= 2 && !peer) { if (!parse_awg_string(&device->i3, "i3", argv[1])) goto error; device->flags |= WGDEVICE_HAS_I3; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "i4") && argc >= 2 && !peer) { if (!parse_awg_string(&device->i4, "i4", argv[1])) goto error; device->flags |= WGDEVICE_HAS_I4; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "i5") && argc >= 2 && !peer) { if (!parse_awg_string(&device->i5, "i5", argv[1])) goto error; device->flags |= WGDEVICE_HAS_I5; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "j1") && argc >= 2 && !peer) { if (!parse_awg_string(&device->j1, "j1", argv[1])) goto error; device->flags |= WGDEVICE_HAS_J1; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "j2") && argc >= 2 && !peer) { if (!parse_awg_string(&device->j2, "j2", argv[1])) goto error; device->flags |= WGDEVICE_HAS_J2; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "j3") && argc >= 2 && !peer) { if (!parse_awg_string(&device->j3, "j3", argv[1])) goto error; device->flags |= WGDEVICE_HAS_J3; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "itime") && argc >= 2 && !peer) { if (!parse_uint32(&device->itime, "itime", argv[1])) goto error; device->flags |= WGDEVICE_HAS_ITIME; argv += 2; - argc -=2; + argc -= 2; } else if (!strcmp(argv[0], "peer") && argc >= 2) { struct wgpeer *new_peer = calloc(1, sizeof(*new_peer)); diff --git a/src/containers.h b/src/containers.h index 7ba9fac..ec5c2e2 100644 --- a/src/containers.h +++ b/src/containers.h @@ -88,18 +88,18 @@ enum { WGDEVICE_HAS_S3 = 1U << 10, WGDEVICE_HAS_S4 = 1U << 11, WGDEVICE_HAS_H1 = 1U << 12, - WGDEVICE_HAS_H2 = 1U << 12, - WGDEVICE_HAS_H3 = 1U << 13, - WGDEVICE_HAS_H4 = 1U << 14, - WGDEVICE_HAS_I1 = 1U << 15, - WGDEVICE_HAS_I2 = 1U << 16, - WGDEVICE_HAS_I3 = 1U << 17, - WGDEVICE_HAS_I4 = 1U << 18, - WGDEVICE_HAS_I5 = 1U << 19, - WGDEVICE_HAS_J1 = 1U << 20, - WGDEVICE_HAS_J2 = 1U << 21, - WGDEVICE_HAS_J3 = 1U << 22, - WGDEVICE_HAS_ITIME = 1U << 23 + WGDEVICE_HAS_H2 = 1U << 13, + WGDEVICE_HAS_H3 = 1U << 14, + WGDEVICE_HAS_H4 = 1U << 15, + WGDEVICE_HAS_I1 = 1U << 16, + WGDEVICE_HAS_I2 = 1U << 17, + WGDEVICE_HAS_I3 = 1U << 18, + WGDEVICE_HAS_I4 = 1U << 19, + WGDEVICE_HAS_I5 = 1U << 20, + WGDEVICE_HAS_J1 = 1U << 21, + WGDEVICE_HAS_J2 = 1U << 22, + WGDEVICE_HAS_J3 = 1U << 23, + WGDEVICE_HAS_ITIME = 1U << 24 }; struct wgdevice { diff --git a/src/ipc-freebsd.h b/src/ipc-freebsd.h index 52f9f34..119bc20 100644 --- a/src/ipc-freebsd.h +++ b/src/ipc-freebsd.h @@ -145,6 +145,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->init_packet_magic_header = strdup((const char*)binary); + if (!dev->init_packet_magic_header) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_H1; } } @@ -153,6 +157,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->response_packet_magic_header = strdup((const char*)binary); + if (!dev->response_packet_magic_header) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_H2; } } @@ -161,6 +169,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->underload_packet_magic_header = strdup((const char*)binary); + if (!dev->underload_packet_magic_header) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_H3; } } @@ -169,6 +181,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->transport_packet_magic_header = strdup((const char*)binary); + if (!dev->transport_packet_magic_header) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_H4; } } @@ -178,6 +194,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->i1 = strdup((const char*)binary); + if (!dev->i1) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_I1; } } @@ -187,6 +207,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->i2 = strdup((const char*)binary); + if (!dev->i2) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_I2; } } @@ -196,6 +220,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->i3 = strdup((const char*)binary); + if (!dev->i3) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_I3; } } @@ -205,6 +233,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->i4 = strdup((const char*)binary); + if (!dev->i4) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_I4; } } @@ -214,6 +246,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->i5 = strdup((const char*)binary); + if (!dev->i5) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_I5; } } @@ -223,6 +259,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->j1 = strdup((const char*)binary); + if (!dev->j1) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_J1; } } @@ -232,6 +272,10 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->j2 = strdup((const char*)binary); + if (!dev->j2) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_J2; } } @@ -241,10 +285,14 @@ static int kernel_get_device(struct wgdevice **device, const char *ifname) if (binary && size < MAX_AWG_STRING_LEN) { dev->j3 = strdup((const char*)binary); + if (!dev->j3) { + ret = ENOMEM; + goto err; + } dev->flags |= WGDEVICE_HAS_J3; } } - if (nvlist_exists_binary(nvl_device, "itime")) + if (nvlist_exists_number(nvl_device, "itime")) { number = nvlist_get_number(nvl_device, "itime"); if (number <= UINT32_MAX) @@ -450,13 +498,13 @@ static int kernel_set_device(struct wgdevice *dev) if (dev->flags & WGDEVICE_HAS_S4) nvlist_add_number(nvl_device, "s4", dev->transport_packet_junk_size); if (dev->flags & WGDEVICE_HAS_H1) - nvlist_add_binary(nvl_device, "h1", dev->init_packet_magic_header, strlen(dev->h1) + 1); + nvlist_add_binary(nvl_device, "h1", dev->init_packet_magic_header, strlen(dev->init_packet_magic_header) + 1); if (dev->flags & WGDEVICE_HAS_H2) - nvlist_add_binary(nvl_device, "h2", dev->response_packet_magic_header, strlen(dev->h2) + 1); + nvlist_add_binary(nvl_device, "h2", dev->response_packet_magic_header, strlen(dev->response_packet_magic_header) + 1); if (dev->flags & WGDEVICE_HAS_H3) - nvlist_add_binary(nvl_device, "h3", dev->underload_packet_magic_header, strlen(dev->h3) + 1); + nvlist_add_binary(nvl_device, "h3", dev->underload_packet_magic_header, strlen(dev->underload_packet_magic_header) + 1); if (dev->flags & WGDEVICE_HAS_H4) - nvlist_add_binary(nvl_device, "h4", dev->transport_packet_magic_header, strlen(dev->h4) + 1); + nvlist_add_binary(nvl_device, "h4", dev->transport_packet_magic_header, strlen(dev->transport_packet_magic_header) + 1); if (dev->flags & WGDEVICE_HAS_I1) nvlist_add_binary(nvl_device, "i1", dev->i1, strlen(dev->i1) + 1); if (dev->flags & WGDEVICE_HAS_I2) diff --git a/src/ipc-linux.h b/src/ipc-linux.h index 8c2e682..be2855b 100644 --- a/src/ipc-linux.h +++ b/src/ipc-linux.h @@ -550,86 +550,137 @@ static int parse_device(const struct nlattr *attr, void *data) case WGDEVICE_A_H1: if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->init_packet_magic_header = strdup(mnl_attr_get_str(attr)); + if (!device->init_packet_magic_header) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_H1; } break; case WGDEVICE_A_H2: if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->response_packet_magic_header = strdup(mnl_attr_get_str(attr)); + if (!device->response_packet_magic_header) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_H2; } break; case WGDEVICE_A_H3: if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->underload_packet_magic_header = strdup(mnl_attr_get_str(attr)); + if (!device->underload_packet_magic_header) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_H3; } break; case WGDEVICE_A_H4: if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->transport_packet_magic_header = strdup(mnl_attr_get_str(attr)); + if (!device->transport_packet_magic_header) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_H4; } break; case WGDEVICE_A_I1: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->i1 = strdup(mnl_attr_get_str(attr)); + if (!device->i1) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_I1; } break; case WGDEVICE_A_I2: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->i2 = strdup(mnl_attr_get_str(attr)); + if (!device->i2) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_I2; } break; case WGDEVICE_A_I3: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->i3 = strdup(mnl_attr_get_str(attr)); + if (!device->i3) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_I3; } break; case WGDEVICE_A_I4: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->i4 = strdup(mnl_attr_get_str(attr)); + if (!device->i4) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_I4; } break; case WGDEVICE_A_I5: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->i5 = strdup(mnl_attr_get_str(attr)); + if (!device->i5) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_I5; } break; case WGDEVICE_A_J1: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->j1 = strdup(mnl_attr_get_str(attr)); + if (!device->j1) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_J1; } break; case WGDEVICE_A_J2: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->j2 = strdup(mnl_attr_get_str(attr)); + if (!device->j2) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_J2; } break; case WGDEVICE_A_J3: - if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_STRING)) { device->j3 = strdup(mnl_attr_get_str(attr)); + if (!device->j3) { + perror("strdup"); + return MNL_CB_ERROR; + } + device->flags |= WGDEVICE_HAS_J3; } break; case WGDEVICE_A_ITIME: - if (!mnl_attr_validate(attr, MNL_TYPE_U32)) - { + if (!mnl_attr_validate(attr, MNL_TYPE_U32)) { device->itime = mnl_attr_get_u32(attr); device->flags |= WGDEVICE_HAS_ITIME; } diff --git a/src/ipc-openbsd.h b/src/ipc-openbsd.h index 231ff77..c3606f6 100644 --- a/src/ipc-openbsd.h +++ b/src/ipc-openbsd.h @@ -147,69 +147,105 @@ static int kernel_get_device(struct wgdevice **device, const char *iface) if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H1) { dev->init_packet_magic_header = strdup(wg_iface->i_init_packet_magic_header); + if (!dev->init_packet_magic_header) + goto out; + dev->flags |= WGDEVICE_HAS_H1; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H2) { dev->response_packet_magic_header = strdup(wg_iface->i_response_packet_magic_header); + if (!dev->response_packet_magic_header) + goto out; + dev->flags |= WGDEVICE_HAS_H2; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H3) { dev->underload_packet_magic_header = strdup(wg_iface->i_underload_packet_magic_header); + if (!dev->underload_packet_magic_header) + goto out; + dev->flags |= WGDEVICE_HAS_H3; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H4) { dev->transport_packet_magic_header = strdup(wg_iface->i_transport_packet_magic_header); + if (!dev->transport_packet_magic_header) + goto out; + dev->flags |= WGDEVICE_HAS_H4; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I1) { dev->i1 = strdup(wg_iface->i_i1); + if (!dev->i1) + goto out; + dev->flags |= WGDEVICE_HAS_I1; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I2) { dev->i2 = strdup(wg_iface->i_i2); + if (!dev->i2) + goto out; + dev->flags |= WGDEVICE_HAS_I2; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I3) { dev->i3 = strdup(wg_iface->i_i3); + if (!dev->i3) + goto out; + dev->flags |= WGDEVICE_HAS_I3; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I4) { dev->i4 = strdup(wg_iface->i_i4); + if (!dev->i4) + goto out; + dev->flags |= WGDEVICE_HAS_I4; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_I5) { dev->i5 = strdup(wg_iface->i_i5); + if (!dev->i5) + goto out; + dev->flags |= WGDEVICE_HAS_I5; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J1) { dev->j1 = strdup(wg_iface->i_j1); + if (!dev->j1) + goto out; + dev->flags |= WGDEVICE_HAS_J1; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J2) { dev->j2 = strdup(wg_iface->i_j2); + if (!dev->j2) + goto out; + dev->flags |= WGDEVICE_HAS_J2; } if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_J3) { dev->j3 = strdup(wg_iface->i_j3); + if (!dev->j3) + goto out; + dev->flags |= WGDEVICE_HAS_J3; } @@ -368,69 +404,105 @@ static int kernel_set_device(struct wgdevice *dev) if (dev->flags & WGDEVICE_HAS_H1) { wg_iface->i_init_packet_magic_header = strdup(dev->init_packet_magic_header); + if (!wg_iface->i_init_packet_magic_header) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H1; } if (dev->flags & WGDEVICE_HAS_H2) { wg_iface->i_response_packet_magic_header = strdup(dev->response_packet_magic_header); + if (!wg_iface->i_response_packet_magic_header) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H2; } if (dev->flags & WGDEVICE_HAS_H3) { wg_iface->i_underload_packet_magic_header = strdup(dev->underload_packet_magic_header); + if (!wg_iface->i_underload_packet_magic_header) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H3; } if (dev->flags & WGDEVICE_HAS_H4) { wg_iface->i_transport_packet_magic_header = strdup(dev->transport_packet_magic_header); + if (!wg_iface->i_transport_packet_magic_header) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_H4; } if (dev->flags & WGDEVICE_HAS_I1) { wg_iface->i_i1 = strdup(dev->i1); + if (!wg_iface->i_i1) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I1; } if (dev->flags & WGDEVICE_HAS_I2) { wg_iface->i_i2 = strdup(dev->i2); + if (!wg_iface->i_i2) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I2; } if (dev->flags & WGDEVICE_HAS_I3) { wg_iface->i_i3 = strdup(dev->i3); + if (!wg_iface->i_i3) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I3; } if (dev->flags & WGDEVICE_HAS_I4) { wg_iface->i_i4 = strdup(dev->i4); + if (!wg_iface->i_i4) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I4; } if (dev->flags & WGDEVICE_HAS_I5) { wg_iface->i_i5 = strdup(dev->i5); + if (!wg_iface->i_i5) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_I5; } if (dev->flags & WGDEVICE_HAS_J1) { wg_iface->i_j1 = strdup(dev->j1); + if (!wg_iface->i_j1) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J1; } if (dev->flags & WGDEVICE_HAS_J2) { wg_iface->i_j2 = strdup(dev->j2); + if (!wg_iface->i_j2) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J2; } if (dev->flags & WGDEVICE_HAS_J3) { wg_iface->i_j3 = strdup(dev->j3); + if (!wg_iface->i_j3) + goto out; + wg_iface->i_flags |= WG_INTERFACE_DEVICE_HAS_J3; } @@ -495,7 +567,7 @@ static int kernel_set_device(struct wgdevice *dev) out: ret = -errno; - if (wgdata.wgd_interface) { + if (wg_iface) { if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H1) free(wg_iface->i_init_packet_magic_header); if (wg_iface->i_flags & WG_INTERFACE_DEVICE_HAS_H2) diff --git a/src/ipc-uapi.h b/src/ipc-uapi.h index b6cfafb..fb44f10 100644 --- a/src/ipc-uapi.h +++ b/src/ipc-uapi.h @@ -251,49 +251,101 @@ static int userspace_get_device(struct wgdevice **out, const char *iface) dev->flags |= WGDEVICE_HAS_S4; } else if(!peer && !strcmp(key, "h1")) { dev->init_packet_magic_header = strdup(value); + if (!dev->init_packet_magic_header) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_H1; } else if(!peer && !strcmp(key, "h2")) { dev->response_packet_magic_header = strdup(value); + if (!dev->response_packet_magic_header) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_H2; } else if(!peer && !strcmp(key, "h3")) { dev->underload_packet_magic_header = strdup(value); + if (!dev->underload_packet_magic_header) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_H3; } else if(!peer && !strcmp(key, "h4")) { dev->transport_packet_magic_header = strdup(value); + if (!dev->transport_packet_magic_header) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_H4; } else if (!peer && !strcmp(key, "i1")) { dev->i1 = strdup(value); + if (!dev->i1) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_I1; - } - else if (!peer && !strcmp(key, "i2")) { + } else if (!peer && !strcmp(key, "i2")) { dev->i2 = strdup(value); + if (!dev->i2) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_I2; - } - else if (!peer && !strcmp(key, "i3")) { + } else if (!peer && !strcmp(key, "i3")) { dev->i3 = strdup(value); + if (!dev->i3) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_I3; - } - else if (!peer && !strcmp(key, "i4")) { + } else if (!peer && !strcmp(key, "i4")) { dev->i4 = strdup(value); + if (!dev->i4) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_I4; - } - else if (!peer && !strcmp(key, "i5")) { + } else if (!peer && !strcmp(key, "i5")) { dev->i5 = strdup(value); + if (!dev->i5) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_I5; - } - else if (!peer && !strcmp(key, "j1")) { + } else if (!peer && !strcmp(key, "j1")) { dev->j1 = strdup(value); + if (!dev->j1) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_J1; - } - else if (!peer && !strcmp(key, "j2")) { + } else if (!peer && !strcmp(key, "j2")) { dev->j2 = strdup(value); + if (!dev->j2) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_J2; - } - else if (!peer && !strcmp(key, "j3")) { + } else if (!peer && !strcmp(key, "j3")) { dev->j3 = strdup(value); + if (!dev->j3) { + ret = -ENOMEM; + goto err; + } + dev->flags |= WGDEVICE_HAS_J3; - } - else if (!peer && !strcmp(key, "itime")) { + } else if (!peer && !strcmp(key, "itime")) { dev->itime = NUM(0xffffffffU); dev->flags |= WGDEVICE_HAS_ITIME; } else if (!strcmp(key, "public_key")) { diff --git a/src/ipc-windows.h b/src/ipc-windows.h index c4da037..c5488cd 100644 --- a/src/ipc-windows.h +++ b/src/ipc-windows.h @@ -673,18 +673,30 @@ static int kernel_set_device(struct wgdevice *dev) out: ret = -errno; if (wg_iface) { - free(wg_iface->InitPacketMagicHeader); - free(wg_iface->ResponsePacketMagicHeader); - free(wg_iface->UnderloadPacketMagicHeader); - free(wg_iface->TransportPacketMagicHeader); - free(wg_iface->I1); - free(wg_iface->I2); - free(wg_iface->I3); - free(wg_iface->I4); - free(wg_iface->I5); - free(wg_iface->J1); - free(wg_iface->J2); - free(wg_iface->J3); + if (wg_iface->InitPacketMagicHeader) + free(wg_iface->InitPacketMagicHeader); + if (wg_iface->ResponsePacketMagicHeader) + free(wg_iface->ResponsePacketMagicHeader); + if (wg_iface->UnderloadPacketMagicHeader) + free(wg_iface->UnderloadPacketMagicHeader); + if (wg_iface->TransportPacketMagicHeader) + free(wg_iface->TransportPacketMagicHeader); + if (wg_iface->I1) + free(wg_iface->I1); + if (wg_iface->I2) + free(wg_iface->I2); + if (wg_iface->I3) + free(wg_iface->I3); + if (wg_iface->I4) + free(wg_iface->I4); + if (wg_iface->I5) + free(wg_iface->I5); + if (wg_iface->J1) + free(wg_iface->J1); + if (wg_iface->J2) + free(wg_iface->J2); + if (wg_iface->J3) + free(wg_iface->J3); } free(wg_iface); CloseHandle(handle); diff --git a/src/show.c b/src/show.c index dbecafb..1175faf 100644 --- a/src/show.c +++ b/src/show.c @@ -308,18 +308,30 @@ static void dump_print(struct wgdevice *device, bool with_interface) printf("%u\t", device->response_packet_junk_size); printf("%u\t", device->cookie_reply_packet_junk_size); printf("%u\t", device->transport_packet_junk_size); - printf("%s\t", device->init_packet_magic_header); - printf("%s\t", device->response_packet_magic_header); - printf("%s\t", device->underload_packet_magic_header); - printf("%s\t", device->transport_packet_magic_header); - printf("%s\t", device->i1); - printf("%s\t", device->i2); - printf("%s\t", device->i3); - printf("%s\t", device->i4); - printf("%s\t", device->i5); - printf("%s\t", device->j1); - printf("%s\t", device->j2); - printf("%s\t", device->j3); + fputs(device->init_packet_magic_header ? device->init_packet_magic_header : "(null)", stdout); + fputc('\t', stdout); + fputs(device->response_packet_magic_header ? device->response_packet_magic_header : "(null)", stdout); + fputc('\t', stdout); + fputs(device->underload_packet_magic_header ? device->underload_packet_magic_header : "(null)", stdout); + fputc('\t', stdout); + fputs(device->transport_packet_magic_header ? device->transport_packet_magic_header : "(null)", stdout); + fputc('\t', stdout); + fputs(device->i1 ? device->i1 : "(null)", stdout); + fputc('\t', stdout); + fputs(device->i2 ? device->i2 : "(null)", stdout); + fputc('\t', stdout); + fputs(device->i3 ? device->i3 : "(null)", stdout); + fputc('\t', stdout); + fputs(device->i4 ? device->i4 : "(null)", stdout); + fputc('\t', stdout); + fputs(device->i5 ? device->i5 : "(null)", stdout); + fputc('\t', stdout); + fputs(device->j1 ? device->j1 : "(null)", stdout); + fputc('\t', stdout); + fputs(device->j2 ? device->j2 : "(null)", stdout); + fputc('\t', stdout); + fputs(device->j3 ? device->j3 : "(null)", stdout); + fputc('\t', stdout); printf("%u\t", device->itime); if (device->fwmark) @@ -373,83 +385,83 @@ static bool ugly_print(struct wgdevice *device, const char *param, bool with_int printf("0x%x\n", device->fwmark); else printf("off\n"); - } else if(!strcmp(param, "jc")) { + } else if (!strcmp(param, "jc")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->junk_packet_count); - } else if(!strcmp(param, "jmin")) { + } else if (!strcmp(param, "jmin")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->junk_packet_min_size); - } else if(!strcmp(param, "jmax")) { + } else if (!strcmp(param, "jmax")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->junk_packet_max_size); - } else if(!strcmp(param, "s1")) { + } else if (!strcmp(param, "s1")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->init_packet_junk_size); - } else if(!strcmp(param, "s2")) { + } else if (!strcmp(param, "s2")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->response_packet_junk_size); - } else if(!strcmp(param, "s3")) { + } else if (!strcmp(param, "s3")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->cookie_reply_packet_junk_size); - } else if(!strcmp(param, "s4")) { + } else if (!strcmp(param, "s4")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->transport_packet_junk_size); - } else if(!strcmp(param, "h1")) { + } else if (!strcmp(param, "h1")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->init_packet_magic_header); - } else if(!strcmp(param, "h2")) { + } else if (!strcmp(param, "h2")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->response_packet_magic_header); - } else if(!strcmp(param, "h3")) { + } else if (!strcmp(param, "h3")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->underload_packet_magic_header); - } else if(!strcmp(param, "h4")) { + } else if (!strcmp(param, "h4")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->transport_packet_magic_header); - } else if(!strcmp(param, "i1")) { + } else if (!strcmp(param, "i1")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->i1); - } else if(!strcmp(param, "i2")) { + } else if (!strcmp(param, "i2")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->i2); - } else if(!strcmp(param, "i3")) { + } else if (!strcmp(param, "i3")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->i3); - } else if(!strcmp(param, "i4")) { + } else if (!strcmp(param, "i4")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->i4); - } else if(!strcmp(param, "i5")) { + } else if (!strcmp(param, "i5")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->i5); - } else if(!strcmp(param, "j1")) { + } else if (!strcmp(param, "j1")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->j1); - } else if(!strcmp(param, "j2")) { + } else if (!strcmp(param, "j2")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->j2); - } else if(!strcmp(param, "j3")) { + } else if (!strcmp(param, "j3")) { if (with_interface) printf("%s\t", device->name); printf("%s\n", device->j3); - } else if(!strcmp(param, "itime")) { + } else if (!strcmp(param, "itime")) { if (with_interface) printf("%s\t", device->name); printf("%u\n", device->itime); diff --git a/src/uapi/windows/wireguard.h b/src/uapi/windows/wireguard.h index 0ddcde6..bfe1caa 100644 --- a/src/uapi/windows/wireguard.h +++ b/src/uapi/windows/wireguard.h @@ -66,18 +66,18 @@ typedef enum WG_IOCTL_INTERFACE_S3 = 1 << 10, WG_IOCTL_INTERFACE_S4 = 1 << 11, WG_IOCTL_INTERFACE_H1 = 1 << 12, - WG_IOCTL_INTERFACE_H2 = 1 << 12, - WG_IOCTL_INTERFACE_H3 = 1 << 13, - WG_IOCTL_INTERFACE_H4 = 1 << 14, - WG_IOCTL_INTERFACE_I1 = 1U << 15, - WG_IOCTL_INTERFACE_I2 = 1U << 16, - WG_IOCTL_INTERFACE_I3 = 1U << 17, - WG_IOCTL_INTERFACE_I4 = 1U << 18, - WG_IOCTL_INTERFACE_I5 = 1U << 19, - WG_IOCTL_INTERFACE_J1 = 1U << 20, - WG_IOCTL_INTERFACE_J2 = 1U << 21, - WG_IOCTL_INTERFACE_J3 = 1U << 22, - WG_IOCTL_INTERFACE_ITIME = 1U << 23 + WG_IOCTL_INTERFACE_H2 = 1 << 13, + WG_IOCTL_INTERFACE_H3 = 1 << 14, + WG_IOCTL_INTERFACE_H4 = 1 << 15, + WG_IOCTL_INTERFACE_I1 = 1U << 16, + WG_IOCTL_INTERFACE_I2 = 1U << 17, + WG_IOCTL_INTERFACE_I3 = 1U << 18, + WG_IOCTL_INTERFACE_I4 = 1U << 19, + WG_IOCTL_INTERFACE_I5 = 1U << 20, + WG_IOCTL_INTERFACE_J1 = 1U << 21, + WG_IOCTL_INTERFACE_J2 = 1U << 22, + WG_IOCTL_INTERFACE_J3 = 1U << 23, + WG_IOCTL_INTERFACE_ITIME = 1U << 24 } WG_IOCTL_INTERFACE_FLAG; typedef struct _WG_IOCTL_INTERFACE diff --git a/src/wg-quick/freebsd.bash b/src/wg-quick/freebsd.bash index 60e7ca6..6213309 100755 --- a/src/wg-quick/freebsd.bash +++ b/src/wg-quick/freebsd.bash @@ -111,7 +111,7 @@ parse_options() { H3);& H4);& I1);& - i2);& + I2);& I3);& I4);& I5);& diff --git a/src/wg-quick/openbsd.bash b/src/wg-quick/openbsd.bash index 210570b..902737c 100755 --- a/src/wg-quick/openbsd.bash +++ b/src/wg-quick/openbsd.bash @@ -82,7 +82,7 @@ parse_options() { H3);& H4);& I1);& - i2);& + I2);& I3);& I4);& I5);&