Compare commits

..

23 commits

Author SHA1 Message Date
Iurii Egorov
35e2612c82 SPEC file for RPM build 2024-02-01 18:52:10 +03:00
Iurii Egorov
a9fe336809 SPEC file for RPM build 2024-02-01 18:51:25 +03:00
Iurii Egorov
e9a7a9ee9f SPEC file for RPM build 2024-02-01 18:50:19 +03:00
Iurii Egorov
02d5d396df Merge branch 'build/deb' into changes-for-kmod 2024-02-01 18:43:06 +03:00
Iurii Egorov
62e3b21cc2 Naming unify 2024-01-19 15:27:39 +03:00
Iurii Egorov
8c1f047442 Naming unify 2024-01-19 15:02:26 +03:00
Iurii Egorov
a4aeb9e195 Bash completions 2024-01-17 19:45:38 +03:00
Mark Puha
1a74f346c1 naming convention fix 2024-01-16 14:13:31 +03:00
Iurii Egorov
761c2d5fb5 Prepare packaging 2023-12-09 18:02:43 +03:00
Iurii Egorov
6cca06e846 Prepare packaging 2023-12-09 17:22:39 +03:00
Iurii Egorov
115b2500d9 Prepare packaging 2023-12-09 17:12:52 +03:00
Iurii Egorov
dc3a0e73e1 Prepare packaging 2023-12-09 16:45:55 +03:00
Iurii Egorov
eec604dc95 Fix wg-quick 2023-11-30 10:18:00 +03:00
Iurii Egorov
98869a07e9 K 2023-11-30 07:47:32 +03:00
Iurii Egorov
17c71156f4 Revert "Change protocol type" 2023-11-30 01:12:24 +03:00
Iurii Egorov
eb2281b577 Change protocol type 2023-11-30 00:58:41 +03:00
Iurii Egorov
ddef70bf70 Change protocol type 2023-11-29 23:47:44 +03:00
Iurii Egorov
72a1165143 Change protocol type 2023-11-29 22:22:28 +03:00
Iurii Egorov
a1551010e5 Change protocol type 2023-11-29 22:22:06 +03:00
Iurii Egorov
d48157dac1 Fix indents 2023-11-20 22:59:53 +03:00
Iurii Egorov
58a1d1d290 Fix indents 2023-11-20 22:59:05 +03:00
Iurii Egorov
9634c932f5 Fix indents 2023-11-20 22:53:21 +03:00
Iurii Egorov
0ef35eed6f UAPI changes for Amnezia kernel module 2023-11-20 22:33:00 +03:00
19 changed files with 90 additions and 598 deletions

View file

@ -1,85 +0,0 @@
name: Linux
on: [push]
jobs:
Build-for-Ubuntu:
name: Build for Ubuntu
runs-on: ubuntu-latest
container:
image: ubuntu:22.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build AmneziaWG tools
run: |
apt -y update &&
apt -y install build-essential &&
cd src &&
make &&
mkdir build &&
cp wg ./build/awg &&
cp wg-quick/linux.bash ./build/awg-quick
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ubuntu-22.04-amneziawg-tools
path: ./src/build
Build-for-Alpine:
name: Build for Alpine
runs-on: ubuntu-latest
container:
image: alpine:3.19
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build AmneziaWG tools
run: |
apk add linux-headers build-base &&
cd src &&
make &&
mkdir build &&
cp wg ./build/awg &&
cp wg-quick/linux.bash ./build/awg-quick
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: alpine-3.19-amneziawg-tools
path: ./src/build
GitHub-Release:
name: GitHub Release
needs: [Build-for-Ubuntu, Build-for-Alpine]
strategy:
matrix:
include:
- os: "ubuntu"
release: "22.04"
- os: "alpine"
release: "3.19"
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Calculate checksums
run: for file in $(find ./${{ matrix.os }}-${{ matrix.release }}-amneziawg-tools/ -type f); do openssl dgst -sha256 -r "$file" | awk '{print $1}' > "${file}.sha256"; done
- name: Zip files
run: zip -r ${{ matrix.os }}-${{ matrix.release }}-amneziawg-tools.zip ${{ matrix.os }}-${{ matrix.release }}-amneziawg-tools
- name: Upload binaries to Release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ./${{ matrix.os }}-${{ matrix.release }}-amneziawg-tools.zip
tag: ${{ github.ref }}
release_name: ${{ github.ref_name }}
overwrite: true
file_glob: true

View file

@ -1,57 +1,69 @@
name: Windows
name: windows-wg
on: [push]
jobs:
Build-for-Windows:
name: Build for Windows
Build-Libs-WireGuard-Windows:
name: 'Build-Libs-WireGuard-Windows'
runs-on: windows-latest
steps:
- name: Setup ccache
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Get sources'
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v4
- name: 'Get Wireguard-Tools'
uses: actions/checkout@v3
with:
repository: amnezia-vpn/amnezia-wg-tools
ref: master
path: windows/wireguard-tools-windows
- name: Build AmneziaWG tools
- name: 'Build WireGuard Tools binary'
working-directory: windows/wireguard-tools-windows
run: |
cmd /c build.cmd
mkdir build
move x64 build\x64
move x86 build\x86
move arm64 build\arm64
- name: Upload artifact
uses: actions/upload-artifact@v4
- name: Archive WG Windows
uses: actions/upload-artifact@v3
with:
retention-days: 1
name: windows-amneziawg-tools
path: build
GitHub-Release:
name: windows-wireguard-tools
path: windows/wireguard-tools-windows/build
github-release:
name: GitHub Release
needs: Build-for-Windows
needs: Build-Libs-WireGuard-Windows
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup | Checkout
uses: actions/checkout@v2
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Setup | Artifacts
uses: actions/download-artifact@v2
- name: Calculate checksums
- name: Setup | Checksums
run: for file in $(find ./ -name '*.exe' ); do openssl dgst -sha256 -r "$file" | awk '{print $1}' > "${file}.sha256"; done
- name: Zip files
- name: Zip ALL
run: for file in *; do zip -r ${file%.*}.zip $file; done
- name: Upload binaries to Release
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: windows-amneziawg-tools.zip
file: windows-wireguard-tools.zip
tag: ${{ github.ref }}
release_name: ${{ github.ref_name }}
overwrite: true
file_glob: true
file_glob: true

View file

@ -46,15 +46,15 @@ WITH_BASHCOMPLETION=yes WITH_WGQUICK=yes WITH_SYSTEMDUNITS=yes -C src
%files
%doc README.md contrib
%license COPYING
%{_bindir}/awg
%{_bindir}/awg-quick
%{_sysconfdir}/amnezia/amneziawg/
%{_datadir}/bash-completion/completions/awg
%{_datadir}/bash-completion/completions/awg-quick
%{_unitdir}/awg-quick@.service
%{_unitdir}/awg-quick.target
%{_mandir}/man8/awg.8*
%{_mandir}/man8/awg-quick.8*
%{_bindir}/wg
%{_bindir}/wg-quick
%{_sysconfdir}/wireguard/
%{_datadir}/bash-completion/completions/wg
%{_datadir}/bash-completion/completions/wg-quick
%{_unitdir}/wg-quick@.service
%{_unitdir}/wg-quick.target
%{_mandir}/man8/wg.8*
%{_mandir}/man8/wg-quick.8*
%changelog
* Thu Feb 1 2024 Yuri Egorov <ye@amnezia.org> - 1.0.20240201-1

View file

@ -29,7 +29,7 @@ if exist .deps/prepared goto :build
:download
echo [+] Downloading %1
curl --retry 3 -#fLo %1 %2 || exit /b 1
curl -#fLo %1 %2 || exit /b 1
echo [+] Verifying %1
for /f %%a in ('CertUtil -hashfile %1 SHA256 ^| findstr /r "^[0-9a-f]*$"') do if not "%%a"=="%~3" exit /b 1
echo [+] Extracting %1
@ -46,7 +46,7 @@ if exist .deps/prepared goto :build
del src\*.exe src\*.o src\wincompat\*.o src\wincompat\*.lib 2> NUL
set LDFLAGS=-s
make --no-print-directory -C src PLATFORM=windows CC=%~2-w64-mingw32-gcc WINDRES=%~2-w64-mingw32-windres V=1 RUNSTATEDIR= SYSTEMDUNITDIR= -j%NUMBER_OF_PROCESSORS% || exit /b 1
move /Y src\wg.exe "%~1\awg.exe" > NUL || exit /b 1
move /Y src\wg.exe "%~1\wg.exe" > NUL || exit /b 1
goto :eof
:error

View file

@ -62,8 +62,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_REPLACE_ALLOWEDIPS = 1U << 1
};
enum wgpeer_attribute {
WGPEER_A_UNSPEC,
@ -77,7 +76,6 @@ enum wgpeer_attribute {
WGPEER_A_TX_BYTES,
WGPEER_A_ALLOWEDIPS,
WGPEER_A_PROTOCOL_VERSION,
WGPEER_A_ADVANCED_SECURITY,
__WGPEER_A_LAST
};

View file

@ -2,30 +2,20 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
# Copyright (C) 2024 Amnezia VPN. All Rights Reserved.
exec < <(exec awg show all dump)
exec < <(exec wg show all dump)
printf '{'
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 fwmark
printf '\t"%s": {' "$device"
delim=$'\n'
[[ $private_key == "(none)" ]] || { printf '%s\t\t"privateKey": "%s"' "$delim" "$private_key"; delim=$',\n'; }
[[ $public_key == "(none)" ]] || { printf '%s\t\t"publicKey": "%s"' "$delim" "$public_key"; delim=$',\n'; }
[[ $listen_port == "0" ]] || { printf '%s\t\t"listenPort": %u' "$delim" $(( $listen_port )); delim=$',\n'; }
[[ $jc == "0" ]] || { printf '%s\t\t"jc": %u' "$delim" $(( $jc )); delim=$',\n'; }
[[ $jmin == "0" ]] || { printf '%s\t\t"jmin": %u' "$delim" $(( $jmin )); delim=$',\n'; }
[[ $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'; }
[[ $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'; }
[[ $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'

View file

@ -1,24 +0,0 @@
=== Dynamic peers authentication example ===
This example shows how to utilize netlink's multicast notifications
in AmneziaWG kernel module to provide dynamic peer authentication.
To compile it, you must install some pre-requisites:
```shell
apt-get install build-essential pkg-config libnl-3-dev libnl-genl-3-dev
```
After that, build example with the following command:
```shell
gcc notification-listener.c $(pkg-config --cflags --libs libnl-3.0 libnl-genl-3.0) -o notification-listener
```
Bring up AWG interface with `awg-quick` as usually, edit `accounts.csv` file accordingly to your needs and then run:
```shell
sudo ./notification-listener ./approve.sh ./accounts.csv
```
### **PLEASE NOTE: THIS EXAMPLE AS WELL AS OVERALL DYNAMIC AUTHENTICATION MECHANISM AND LEGACY CLIENTS' SUPPORT IN AMNEZIAWG IS SPONSORED BY [WINDSCRIBE LIMITED](https://windscribe.com)**

View file

@ -1,2 +0,0 @@
Public Key,Allowed Ips,PSK
/Ca5004uiLJVBqSPaBUKg5zBszO9qbzEUCWmVkelkjY=,"10.8.1.10/32",E37VXqGtGvwftop/uFsbZcIO76Ox1kMmB6Sz/JoIw2I=
1 Public Key Allowed Ips PSK
2 /Ca5004uiLJVBqSPaBUKg5zBszO9qbzEUCWmVkelkjY= 10.8.1.10/32 E37VXqGtGvwftop/uFsbZcIO76Ox1kMmB6Sz/JoIw2I=

View file

@ -1,26 +0,0 @@
#!/usr/bin/env bash
ACCOUNTS_FILE=$1
INTERFACE_NAME=$2
PUBLIC_KEY=$3
ENDPOINT=$4
ADVANCED_SECURITY=$5
ACCOUNT_STR=`grep "${PUBLIC_KEY}" "${ACCOUNTS_FILE}"`
if [ "${ACCOUNT_STR}" == "" ]; then
echo "Public key not found in accounts file!"
exit 255
fi
ACCOUNT=(${ACCOUNT_STR//,/ })
ALLOWED_IPS=$(echo ${ACCOUNT[1]}|tr -d '"')
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}"
EXIT_CODE=$?
rm -f "{$PSK_FILE}"
exit ${EXIT_CODE}

View file

@ -1,263 +0,0 @@
#include <errno.h>
#include <signal.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netlink/netlink.h>
#include <netlink/socket.h>
#include <netlink/msg.h>
#include <netlink/attr.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "../../src/uapi/linux/linux/wireguard.h"
#define prerr(...) fprintf(stderr, "Error: " __VA_ARGS__)
#define WG_KEY_LEN 32
#define WG_KEY_LEN_BASE64 ((((WG_KEY_LEN) + 2) / 3) * 4 + 1)
static struct nl_sock *sk = NULL;
static char **cb_argv;
static int cb_argc;
static int cleanup_and_exit(int ret)
{
if (sk != NULL)
nl_socket_free(sk);
exit(ret);
}
static void signal_handler(int sig)
{
cleanup_and_exit(EXIT_SUCCESS);
}
static inline void encode_base64(char dest[static 4], const uint8_t src[static 3])
{
const uint8_t input[] = { (src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63 };
for (unsigned int i = 0; i < 4; ++i)
dest[i] = input[i] + 'A'
+ (((25 - input[i]) >> 8) & 6)
- (((51 - input[i]) >> 8) & 75)
- (((61 - input[i]) >> 8) & 15)
+ (((62 - input[i]) >> 8) & 3);
}
void key_to_base64(char base64[static WG_KEY_LEN_BASE64], const uint8_t key[static WG_KEY_LEN])
{
unsigned int i;
for (i = 0; i < WG_KEY_LEN / 3; ++i)
encode_base64(&base64[i * 4], &key[i * 3]);
encode_base64(&base64[i * 4], (const uint8_t[]){ key[i * 3 + 0], key[i * 3 + 1], 0 });
base64[WG_KEY_LEN_BASE64 - 2] = '=';
base64[WG_KEY_LEN_BASE64 - 1] = '\0';
}
static char *key(const uint8_t key[static WG_KEY_LEN])
{
static char base64[WG_KEY_LEN_BASE64];
key_to_base64(base64, key);
return base64;
}
static char *endpoint(const struct sockaddr *addr)
{
char host[4096 + 1];
char service[512 + 1];
static char buf[sizeof(host) + sizeof(service) + 4];
int ret;
socklen_t addr_len = 0;
memset(buf, 0, sizeof(buf));
if (addr->sa_family == AF_INET)
addr_len = sizeof(struct sockaddr_in);
else if (addr->sa_family == AF_INET6)
addr_len = sizeof(struct sockaddr_in6);
ret = getnameinfo(addr, addr_len, host, sizeof(host), service, sizeof(service), NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST);
if (ret) {
strncpy(buf, gai_strerror(ret), sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
} else
snprintf(buf, sizeof(buf), (addr->sa_family == AF_INET6 && strchr(host, ':')) ? "[%s]:%s" : "%s:%s", host, service);
return buf;
}
static int get_ifname(struct nlattr *tb[], char **ifname)
{
if (tb[WGDEVICE_A_IFNAME] == NULL)
return -1;
*ifname = nla_data(tb[WGDEVICE_A_IFNAME]);
return 0;
}
static int get_pubkey(struct nlattr *peer[], char **pubkey)
{
if (peer[WGPEER_A_PUBLIC_KEY] == NULL)
return -1;
*pubkey = key(nla_data(peer[WGPEER_A_PUBLIC_KEY]));
return 0;
}
static int get_endpoint(struct nlattr *peer[], char **endpoint_ip)
{
if (peer[WGPEER_A_ENDPOINT] == NULL)
return -1;
*endpoint_ip = endpoint(nla_data(peer[WGPEER_A_ENDPOINT]));
return 0;
}
static int run_callback(char *ifname, char *pubkey, char *endpoint_ip, bool advanced_security)
{
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++) {
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] = NULL;
int child_pid = fork(), ret;
if (child_pid < 0) {
prerr("failed to spawn child process: %d\n", child_pid);
return child_pid;
} else if (child_pid == 0) {
execv(cb_argv[1], new_argv);
exit(0);
} else {
waitpid(child_pid, &ret, 0);
}
free(new_argv);
return ret;
}
static int netlink_callback(struct nl_msg *msg, void *arg)
{
struct nlmsghdr *ret_hdr = nlmsg_hdr(msg);
struct genlmsghdr *gnlh = nlmsg_data(ret_hdr);
struct nlattr *tb[WGDEVICE_A_MAX + 1];
struct nlattr *peer[WGPEER_A_MAX + 1];
nla_parse(tb, WGDEVICE_A_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
char *ifname, *pubkey, *endpoint_ip;
bool advanced_security = false;
int cb_ret;
switch (gnlh->cmd) {
case WG_CMD_UNKNOWN_PEER:
if (get_ifname(tb, &ifname) < 0) {
prerr("unknown interface name!\n");
return NL_SKIP;
}
if (nla_parse_nested(peer, WGPEER_A_MAX, tb[WGDEVICE_A_PEER], NULL)) {
prerr("failed to parse nested peer!\n");
return NL_SKIP;
}
if (get_pubkey(peer, &pubkey)) {
prerr("invalid public key!\n");
return NL_SKIP;
}
if (get_endpoint(peer, &endpoint_ip)) {
prerr("invalid endpoint!\n");
return NL_SKIP;
}
if (nla_get_flag(peer[WGPEER_A_ADVANCED_SECURITY])) {
advanced_security = true;
}
if (cb_ret = run_callback(ifname, pubkey, endpoint_ip, advanced_security)) {
prerr("failed to execute callback script: %d!\n", cb_ret);
return NL_SKIP;
}
printf("Callback executed successfully.\n");
break;
default:
return NL_SKIP;
}
return 0;
}
int main(int argc, char *argv[])
{
int ret;
int sk_fd;
fd_set rfds;
if (argc < 2) {
prerr("usage: %s <callback>\n", argv[0]);
cleanup_and_exit(EXIT_FAILURE);
}
cb_argc = argc + 3;
cb_argv = argv;
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
sk = nl_socket_alloc();
if (sk == NULL) {
prerr("unable to allocate Netlink socket!\n");
exit(EXIT_FAILURE);
}
ret = genl_connect(sk);
if (ret < 0) {
prerr("no connect %d!\n", ret);
cleanup_and_exit(EXIT_FAILURE);
}
printf("Netlink socket connected.\n");
ret = genl_ctrl_resolve_grp(sk, WG_GENL_NAME, WG_MULTICAST_GROUP_AUTH);
if (ret < 0) {
prerr("auth group not found %d!\n", ret);
cleanup_and_exit(EXIT_FAILURE);
}
ret = nl_socket_add_membership(sk, ret);
if (ret < 0) {
prerr("unable to join multicast group %d!\n", ret);
cleanup_and_exit(EXIT_FAILURE);
}
nl_socket_disable_seq_check(sk);
ret = nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, netlink_callback, NULL);
if (ret < 0) {
prerr("unable to register callback %d!\n", ret);
cleanup_and_exit(EXIT_FAILURE);
}
while (1) {
FD_ZERO(&rfds);
sk_fd = nl_socket_get_fd(sk);
FD_SET(sk_fd, &rfds);
ret = select(sk_fd + 1, &rfds, NULL, NULL, NULL);
if (ret < 0)
break;
ret = nl_recvmsgs_default(sk);
if (ret < 0) {
prerr("error receiving message %d!\n", ret);
cleanup_and_exit(EXIT_FAILURE);
}
}
cleanup_and_exit(EXIT_FAILURE);
}

View file

@ -447,41 +447,6 @@ static inline bool parse_uint32(uint32_t *device_value, const char *name, const
return true;
}
static inline bool parse_bool(bool *device_value, const char *name, const char *value) {
if (!strlen(value)) {
fprintf(stderr, "Unable to parse empty string\n");
return false;
}
if (!strcasecmp(value, "off")) {
*device_value = false;
return true;
}
if (!strcasecmp(value, "on")) {
*device_value = true;
return true;
}
if (!char_is_digit(value[0]))
goto err;
char *end;
uint32_t ret;
ret = strtoul(value, &end, 10);
if (*end) {
fprintf(stderr, "Unable to parse %s: `%s'\n", name, value);
exit(1);
}
*device_value = ret != 0;
return true;
err:
fprintf(stderr, "Boolean value is neither on/off nor 0/1: `%s'\n", value);
return false;
}
static bool process_line(struct config_ctx *ctx, const char *line)
{
const char *value;
@ -575,10 +540,6 @@ static bool process_line(struct config_ctx *ctx, const char *line)
ret = parse_key(ctx->last_peer->preshared_key, value);
if (ret)
ctx->last_peer->flags |= WGPEER_HAS_PRESHARED_KEY;
} else if (key_match("AdvancedSecurity")) {
ret = parse_bool(&ctx->last_peer->advanced_security, "AdvancedSecurity", value);
if (ret)
ctx->last_peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
} else
goto error;
} else
@ -813,12 +774,6 @@ struct wgdevice *config_read_cmd(const char *argv[], int argc)
peer->flags |= WGPEER_HAS_PRESHARED_KEY;
argv += 2;
argc -= 2;
} else if (!strcmp(argv[0], "advanced-security") && argc >= 2 && peer) {
if (!parse_bool(&peer->advanced_security, "AdvancedSecurity", argv[1]))
goto error;
peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
argv += 2;
argc -= 2;
} else {
fprintf(stderr, "Invalid argument: %s\n", argv[0]);
goto error;

View file

@ -7,7 +7,6 @@
#define CONTAINERS_H
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <sys/socket.h>
@ -44,8 +43,7 @@ enum {
WGPEER_REPLACE_ALLOWEDIPS = 1U << 1,
WGPEER_HAS_PUBLIC_KEY = 1U << 2,
WGPEER_HAS_PRESHARED_KEY = 1U << 3,
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4,
WGPEER_HAS_ADVANCED_SECURITY = 1U << 5
WGPEER_HAS_PERSISTENT_KEEPALIVE_INTERVAL = 1U << 4
};
struct wgpeer {
@ -64,8 +62,6 @@ struct wgpeer {
uint64_t rx_bytes, tx_bytes;
uint16_t persistent_keepalive_interval;
bool advanced_security;
struct wgallowedip *first_allowedip, *last_allowedip;
struct wgpeer *next_peer;
};
@ -100,7 +96,7 @@ struct wgdevice {
uint16_t listen_port;
struct wgpeer *first_peer, *last_peer;
uint16_t junk_packet_count;
uint16_t junk_packet_min_size;
uint16_t junk_packet_max_size;

View file

@ -221,11 +221,6 @@ 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 (flags) {
if (!mnl_attr_put_u32_check(nlh, SOCKET_BUFFER_SIZE, WGPEER_A_FLAGS, flags))
goto toobig_peers;
@ -394,25 +389,6 @@ static int parse_peer(const struct nlattr *attr, void *data)
if (!mnl_attr_validate(attr, MNL_TYPE_U64))
peer->tx_bytes = mnl_attr_get_u64(attr);
break;
case WGPEER_A_FLAGS:
if (!mnl_attr_validate(attr, MNL_TYPE_U32)) {
uint32_t flags = mnl_attr_get_u32(attr);
if (flags & WGPEER_F_HAS_ADVANCED_SECURITY && !(peer->flags & WGPEER_HAS_ADVANCED_SECURITY)) {
peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
peer->advanced_security = false;
}
}
break;
case WGPEER_A_ADVANCED_SECURITY:
if (!mnl_attr_validate(attr, MNL_TYPE_FLAG)) {
peer->advanced_security = true;
if (!(peer->flags & WGPEER_HAS_ADVANCED_SECURITY)) {
peer->flags |= WGPEER_HAS_ADVANCED_SECURITY;
}
}
break;
case WGPEER_A_ALLOWEDIPS:
return mnl_attr_parse_nested(attr, parse_allowedips, peer);
}

View file

@ -26,7 +26,7 @@ static FILE *userspace_interface_file(const char *iface)
if (!CreateWellKnownSid(WinLocalSystemSid, NULL, &expected_sid, &bytes))
goto err;
snprintf(fname, sizeof(fname), "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\AmneziaWG\\%s", iface);
snprintf(fname, sizeof(fname), "\\\\.\\pipe\\ProtectedPrefix\\Administrators\\WireGuard\\%s", iface);
pipe_handle = CreateFileA(fname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (pipe_handle == INVALID_HANDLE_VALUE)
goto err;
@ -62,7 +62,7 @@ static bool userspace_has_wireguard_interface(const char *iface)
if (have_cached_interfaces)
return hashtable_find_entry(&cached_interfaces, iface) != NULL;
snprintf(fname, sizeof(fname), "ProtectedPrefix\\Administrators\\AmneziaWG\\%s", iface);
snprintf(fname, sizeof(fname), "ProtectedPrefix\\Administrators\\WireGuard\\%s", iface);
find_handle = FindFirstFile("\\\\.\\pipe\\*", &find_data);
if (find_handle == INVALID_HANDLE_VALUE)
return -EIO;
@ -78,7 +78,7 @@ static bool userspace_has_wireguard_interface(const char *iface)
static int userspace_get_wireguard_interfaces(struct string_list *list)
{
static const char prefix[] = "ProtectedPrefix\\Administrators\\AmneziaWG\\";
static const char prefix[] = "ProtectedPrefix\\Administrators\\WireGuard\\";
WIN32_FIND_DATA find_data;
HANDLE find_handle;
char *iface;

View file

@ -73,10 +73,6 @@ static int userspace_set_device(struct wgdevice *dev)
for_each_wgpeer(dev, peer) {
key_to_hex(hex, peer->public_key);
fprintf(f, "public_key=%s\n", hex);
if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
ret = -EINVAL;
goto out;
}
if (peer->flags & WGPEER_REMOVE_ME) {
fprintf(f, "remove=true\n");
continue;

View file

@ -18,7 +18,7 @@ int set_main(int argc, const char *argv[])
int ret = 1;
if (argc < 3) {
fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>] [advanced-security <on|off>]...] ]...\n", PROG_NAME, argv[0]);
fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
return 1;
}

View file

@ -73,9 +73,6 @@ int showconf_main(int argc, const char *argv[])
key_to_base64(base64, peer->preshared_key);
printf("PresharedKey = %s\n", base64);
}
if (peer->flags & WGPEER_HAS_ADVANCED_SECURITY) {
printf("AdvancedSecurity = %s\n", peer->advanced_security ? "on" : "off");
}
if (peer->first_allowedip)
printf("AllowedIPs = ");
for_each_wgallowedip(peer, allowedip) {

View file

@ -111,9 +111,6 @@
* most recent protocol will be used when
* this is unset. Otherwise, must be set
* to 1.
* WGPEER_A_ADVANCED_SECURITY: flag indicating that advanced security
* techniques provided by AmneziaWG should
* be used.
* 0: NLA_NESTED
* ...
* ...
@ -129,25 +126,6 @@
* of a peer, it likely should not be specified in subsequent fragments.
*
* If an error occurs, NLMSG_ERROR will reply containing an errno.
*
* WG_CMD_UNKNOWN_PEER
* ----------------------
*
* This command is sent on the multicast group WG_MULTICAST_GROUP_AUTH
* when the initiation message received from a peer with an unknown public
* key.
* The kernel will send a single message containing the
* following tree of nested items:
*
* WGDEVICE_A_IFINDEX: NLA_U32
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
* 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.
*
*/
#ifndef _WG_UAPI_WIREGUARD_H
@ -158,12 +136,9 @@
#define WG_KEY_LEN 32
#define WG_MULTICAST_GROUP_AUTH "auth"
enum wg_cmd {
WG_CMD_GET_DEVICE,
WG_CMD_SET_DEVICE,
WG_CMD_UNKNOWN_PEER,
__WG_CMD_MAX
};
#define WG_CMD_MAX (__WG_CMD_MAX - 1)
@ -191,7 +166,6 @@ enum wgdevice_attribute {
WGDEVICE_A_H2,
WGDEVICE_A_H3,
WGDEVICE_A_H4,
WGDEVICE_A_PEER,
__WGDEVICE_A_LAST
};
#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
@ -200,7 +174,6 @@ enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1U << 0,
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
WGPEER_F_UPDATE_ONLY = 1U << 2,
WGPEER_F_HAS_ADVANCED_SECURITY = 1U << 3,
__WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS |
WGPEER_F_UPDATE_ONLY
};
@ -216,7 +189,6 @@ enum wgpeer_attribute {
WGPEER_A_TX_BYTES,
WGPEER_A_ALLOWEDIPS,
WGPEER_A_PROTOCOL_VERSION,
WGPEER_A_ADVANCED_SECURITY,
__WGPEER_A_LAST
};
#define WGPEER_A_MAX (__WGPEER_A_LAST - 1)

View file

@ -27,11 +27,11 @@
#include <sys/param.h>
#include <sys/system_properties.h>
#ifndef AWG_PACKAGE_NAME
#define AWG_PACKAGE_NAME "org.amnezia.awg"
#ifndef WG_PACKAGE_NAME
#define WG_PACKAGE_NAME "com.wireguard.android"
#endif
#ifndef AWG_CONFIG_SEARCH_PATHS
#define AWG_CONFIG_SEARCH_PATHS "/data/misc/amneziawg /data/data/" AWG_PACKAGE_NAME "/files"
#ifndef WG_CONFIG_SEARCH_PATHS
#define WG_CONFIG_SEARCH_PATHS "/data/misc/wireguard /data/data/" WG_PACKAGE_NAME "/files"
#endif
#define _printf_(x, y) __attribute__((format(printf, x, y)))
@ -636,7 +636,7 @@ static void add_if(const char *iface)
if (is_asecurity_on)
cmd("amneziawg-go %s", iface);
else
cmd("ip link add %s type amneziawg", iface);
cmd("ip link add %s type wireguard", iface);
}
static void del_if(const char *iface)
@ -648,7 +648,7 @@ static void del_if(const char *iface)
regmatch_t matches[2];
char *netid = NULL;
_cleanup_free_ char *rule_regex = concat("0xc([0-9a-f]+)/0xcffff lookup ", iface, NULL);
_cleanup_free_ char *iptables_regex = concat("^-A (.* --comment \"amneziawg rule ", iface, "\"[^\n]*)\n*$", NULL);
_cleanup_free_ char *iptables_regex = concat("^-A (.* --comment \"wireguard rule ", iface, "\"[^\n]*)\n*$", NULL);
xregcomp(&rule_reg, rule_regex, REG_EXTENDED);
xregcomp(&iptables_reg, iptables_regex, REG_EXTENDED);
@ -684,7 +684,7 @@ static bool should_block_ipv6(const char *iface)
DEFINE_CMD(c);
bool has_ipv6 = false, has_all_none = true;
for (char *endpoint = cmd_ret(&c, "awg show %s endpoints", iface); endpoint; endpoint = cmd_ret(&c, NULL)) {
for (char *endpoint = cmd_ret(&c, "wg show %s endpoints", iface); endpoint; endpoint = cmd_ret(&c, NULL)) {
char *start = strchr(endpoint, '\t');
if (!start)
@ -705,7 +705,7 @@ static uint16_t determine_listen_port(const char *iface)
char *value;
cmd("ip link set up dev %s", iface);
value = cmd_ret(&c, "awg show %s listen-port", iface);
value = cmd_ret(&c, "wg show %s listen-port", iface);
if (!value)
goto set_back_down;
listen_port = strtoul(value, NULL, 10);
@ -725,12 +725,12 @@ static void up_if(unsigned int *netid, const char *iface, uint16_t listen_port)
while (*netid < 4096)
*netid = random() & 0xfffe;
cmd("awg set %s fwmark 0x20000", iface);
cmd("iptables -I OUTPUT 1 -m mark --mark 0x20000 -j ACCEPT -m comment --comment \"amneziawg rule %s\"", iface);
cmd("ip6tables -I OUTPUT 1 -m mark --mark 0x20000 -j ACCEPT -m comment --comment \"amneziawg rule %s\"", iface);
cmd("wg set %s fwmark 0x20000", iface);
cmd("iptables -I OUTPUT 1 -m mark --mark 0x20000 -j ACCEPT -m comment --comment \"wireguard rule %s\"", iface);
cmd("ip6tables -I OUTPUT 1 -m mark --mark 0x20000 -j ACCEPT -m comment --comment \"wireguard rule %s\"", iface);
if (listen_port) {
cmd("iptables -I INPUT 1 -p udp --dport %u -j ACCEPT -m comment --comment \"amneziawg rule %s\"", listen_port, iface);
cmd("ip6tables -I INPUT 1 -p udp --dport %u -j %s -m comment --comment \"amneziawg rule %s\"", listen_port, should_block_ipv6(iface) ? "DROP" : "ACCEPT", iface);
cmd("iptables -I INPUT 1 -p udp --dport %u -j ACCEPT -m comment --comment \"wireguard rule %s\"", listen_port, iface);
cmd("ip6tables -I INPUT 1 -p udp --dport %u -j %s -m comment --comment \"wireguard rule %s\"", listen_port, should_block_ipv6(iface) ? "DROP" : "ACCEPT", iface);
}
cmd("ip link set up dev %s", iface);
cndc(sdk_version < 31 ? "network create %u vpn 1 1" : "network create %u vpn 1", *netid);
@ -1011,7 +1011,7 @@ static void set_mtu(const char *iface, unsigned int mtu)
if (endpoint_mtu == -1)
endpoint_mtu = 1500;
for (char *endpoint = cmd_ret(&c_endpoints, "awg show %s endpoints", iface); endpoint; endpoint = cmd_ret(&c_endpoints, NULL)) {
for (char *endpoint = cmd_ret(&c_endpoints, "wg show %s endpoints", iface); endpoint; endpoint = cmd_ret(&c_endpoints, NULL)) {
if (regexec(&regex_endpoint, endpoint, ARRAY_SIZE(matches), matches, 0))
continue;
endpoint[matches[1].rm_eo] = '\0';
@ -1034,7 +1034,7 @@ static void set_routes(const char *iface, unsigned int netid)
{
DEFINE_CMD(c);
for (char *allowedips = cmd_ret(&c, "awg show %s allowed-ips", iface); allowedips; allowedips = cmd_ret(&c, NULL)) {
for (char *allowedips = cmd_ret(&c, "wg show %s allowed-ips", iface); allowedips; allowedips = cmd_ret(&c, NULL)) {
char *start = strchr(allowedips, '\t');
if (!start)
@ -1051,7 +1051,7 @@ static void set_routes(const char *iface, unsigned int netid)
static void set_config(const char *iface, const char *config)
{
FILE *config_writer;
_cleanup_free_ char *cmd = concat("awg setconf ", iface, " /proc/self/fd/0", NULL);
_cleanup_free_ char *cmd = concat("wg setconf ", iface, " /proc/self/fd/0", NULL);
int ret;
printf("[#] %s\n", cmd);
@ -1074,13 +1074,13 @@ static void broadcast_change(void)
{
const char *pkg = getenv("CALLING_PACKAGE");
if (!pkg || strcmp(pkg, AWG_PACKAGE_NAME))
cmd("am broadcast -a org.amnezia.awg.action.REFRESH_TUNNEL_STATES " AWG_PACKAGE_NAME);
if (!pkg || strcmp(pkg, WG_PACKAGE_NAME))
cmd("am broadcast -a com.wireguard.android.action.REFRESH_TUNNEL_STATES " WG_PACKAGE_NAME);
}
static void print_search_paths(FILE *file, const char *prefix)
{
_cleanup_free_ char *paths = strdup(AWG_CONFIG_SEARCH_PATHS);
_cleanup_free_ char *paths = strdup(WG_CONFIG_SEARCH_PATHS);
for (char *path = strtok(paths, " "); path; path = strtok(NULL, " "))
fprintf(file, "%s%s\n", prefix, path);
@ -1094,7 +1094,7 @@ static void cmd_usage(const char *program)
" followed by `.conf'. Otherwise, INTERFACE is an interface name, with\n"
" configuration found at:\n\n", program);
print_search_paths(stdout, " - ");
printf( "\n It is to be readable by awg(8)'s `setconf' sub-command, with the exception\n"
printf( "\n It is to be readable by wg(8)'s `setconf' sub-command, with the exception\n"
" of the following additions to the [Interface] section, which are handled by\n"
" this program:\n\n"
" - Address: may be specified one or more times and contains one or more\n"
@ -1103,7 +1103,7 @@ static void cmd_usage(const char *program)
" - DNS: an optional DNS server to use while the device is up.\n"
" - ExcludedApplications: optional blacklist of applications to exclude from the tunnel.\n\n"
" - IncludedApplications: optional whitelist of applications to include in the tunnel.\n\n"
" See awg-quick(8) for more info and examples.\n");
" See wg-quick(8) for more info and examples.\n");
}
static char *cleanup_iface = NULL;
@ -1151,7 +1151,7 @@ static void cmd_down(const char *iface)
DEFINE_CMD(c);
bool found = false;
char *ifaces = cmd_ret(&c, "awg show interfaces");
char *ifaces = cmd_ret(&c, "wg show interfaces");
if (ifaces) {
for (char *eiface = strtok(ifaces, " \n"); eiface; eiface = strtok(NULL, " \n")) {
if (!strcmp(iface, eiface)) {
@ -1161,7 +1161,7 @@ static void cmd_down(const char *iface)
}
}
if (!found) {
fprintf(stderr, "Error: %s is not a AmneziaWG interface\n", iface);
fprintf(stderr, "Error: %s is not a WireGuard interface\n", iface);
exit(EMEDIUMTYPE);
}
@ -1175,7 +1175,7 @@ static void parse_options(char **iface, char **config, unsigned int *mtu, char *
_cleanup_fclose_ FILE *file = NULL;
_cleanup_free_ char *line = NULL;
_cleanup_free_ char *filename = NULL;
_cleanup_free_ char *paths = strdup(AWG_CONFIG_SEARCH_PATHS);
_cleanup_free_ char *paths = strdup(WG_CONFIG_SEARCH_PATHS);
_cleanup_regfree_ regex_t regex_iface = { 0 }, regex_conf = { 0 };
regmatch_t matches[2];
struct stat sbuf;
@ -1260,23 +1260,23 @@ static void parse_options(char **iface, char **config, unsigned int *mtu, char *
} else if (!strncasecmp(clean, "MTU=", 4) && j > 4) {
*mtu = atoi(clean + 4);
continue;
} else if (!strncasecmp(clean, "Jc=", 3) && j > 4) {
} else if (!strncasecmp(clean, "Jc=", 3) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "Jmin=", 5) && j > 4) {
} else if (!strncasecmp(clean, "Jmin=", 5) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "Jmax=", 5) && j > 4) {
} else if (!strncasecmp(clean, "Jmax=", 5) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "S1=", 3) && j > 4) {
} else if (!strncasecmp(clean, "S1=", 3) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "S2=", 3) && j > 4) {
} else if (!strncasecmp(clean, "S2=", 3) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "H1=", 3) && j > 4) {
} else if (!strncasecmp(clean, "H1=", 3) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "H2=", 3) && j > 4) {
} else if (!strncasecmp(clean, "H2=", 3) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "H3=", 3) && j > 4) {
} else if (!strncasecmp(clean, "H3=", 3) && j > 4 {
is_asecurity_on = true;
} else if (!strncasecmp(clean, "H4=", 3) && j > 4) {
} else if (!strncasecmp(clean, "H4=", 3) && j > 4 {
is_asecurity_on = true;
}
}