Merge branch 'dev' of github.com:amnezia-vpn/amnezia-client into dev
This commit is contained in:
commit
f5448fed59
67 changed files with 2326 additions and 752 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
@ -1,6 +1,3 @@
|
||||||
[submodule "client/3rd/wireguard-apple"]
|
|
||||||
path = client/3rd/wireguard-apple
|
|
||||||
url = https://github.com/WireGuard/wireguard-apple
|
|
||||||
[submodule "client/3rd/OpenVPNAdapter"]
|
[submodule "client/3rd/OpenVPNAdapter"]
|
||||||
path = client/3rd/OpenVPNAdapter
|
path = client/3rd/OpenVPNAdapter
|
||||||
url = https://github.com/amnezia-vpn/OpenVPNAdapter.git
|
url = https://github.com/amnezia-vpn/OpenVPNAdapter.git
|
||||||
|
@ -25,3 +22,6 @@
|
||||||
[submodule "client/3rd-prebuilt"]
|
[submodule "client/3rd-prebuilt"]
|
||||||
path = client/3rd-prebuilt
|
path = client/3rd-prebuilt
|
||||||
url = https://github.com/amnezia-vpn/3rd-prebuilt
|
url = https://github.com/amnezia-vpn/3rd-prebuilt
|
||||||
|
[submodule "client/3rd/awg-apple"]
|
||||||
|
path = client/3rd/awg-apple
|
||||||
|
url = https://github.com/amnezia-vpn/awg-apple
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit e8795854a5cf27004fe78caecc90a961688d1d41
|
Subproject commit 15b0ff395d9d372339c5ea8ea35cb2715b975ea9
|
1
client/3rd/awg-apple
vendored
Submodule
1
client/3rd/awg-apple
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit fab07138dbab06ac0de256021e47e273f4df8e88
|
1
client/3rd/wireguard-apple
vendored
1
client/3rd/wireguard-apple
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 23618f994f17d8ad8f2f65d79b4a1e8a0830b334
|
|
|
@ -282,6 +282,7 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.h
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.h
|
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/protocols/awgprotocol.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES ${SOURCES}
|
set(SOURCES ${SOURCES}
|
||||||
|
@ -292,6 +293,7 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/openvpnovercloakprotocol.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/shadowsocksvpnprotocol.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.cpp
|
${CMAKE_CURRENT_LIST_DIR}/protocols/wireguardprotocol.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/protocols/awgprotocol.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -315,8 +315,11 @@ void AmneziaApplication::initModels()
|
||||||
m_cloakConfigModel.reset(new CloakConfigModel(this));
|
m_cloakConfigModel.reset(new CloakConfigModel(this));
|
||||||
m_engine->rootContext()->setContextProperty("CloakConfigModel", m_cloakConfigModel.get());
|
m_engine->rootContext()->setContextProperty("CloakConfigModel", m_cloakConfigModel.get());
|
||||||
|
|
||||||
m_wireguardConfigModel.reset(new WireGuardConfigModel(this));
|
m_wireGuardConfigModel.reset(new WireGuardConfigModel(this));
|
||||||
m_engine->rootContext()->setContextProperty("WireGuardConfigModel", m_wireguardConfigModel.get());
|
m_engine->rootContext()->setContextProperty("WireGuardConfigModel", m_wireGuardConfigModel.get());
|
||||||
|
|
||||||
|
m_awgConfigModel.reset(new AwgConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("AwgConfigModel", m_awgConfigModel.get());
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
#include "ui/models/protocols/ikev2ConfigModel.h"
|
#include "ui/models/protocols/ikev2ConfigModel.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
#include "ui/models/protocols/openvpnConfigModel.h"
|
#include "ui/models/protocols/openvpnConfigModel.h"
|
||||||
#include "ui/models/protocols/shadowsocksConfigModel.h"
|
#include "ui/models/protocols/shadowsocksConfigModel.h"
|
||||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||||
|
@ -97,7 +98,8 @@ private:
|
||||||
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
||||||
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
||||||
QScopedPointer<CloakConfigModel> m_cloakConfigModel;
|
QScopedPointer<CloakConfigModel> m_cloakConfigModel;
|
||||||
QScopedPointer<WireGuardConfigModel> m_wireguardConfigModel;
|
QScopedPointer<WireGuardConfigModel> m_wireGuardConfigModel;
|
||||||
|
QScopedPointer<AwgConfigModel> m_awgConfigModel;
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -138,8 +138,8 @@ android {
|
||||||
resConfig "en"
|
resConfig "en"
|
||||||
minSdkVersion = 24
|
minSdkVersion = 24
|
||||||
targetSdkVersion = 34
|
targetSdkVersion = 34
|
||||||
versionCode 32 // Change to a higher number
|
versionCode 36 // Change to a higher number
|
||||||
versionName "3.0.9" // Change to a higher number
|
versionName "4.0.8" // Change to a higher number
|
||||||
|
|
||||||
javaCompileOptions.annotationProcessorOptions.arguments = [
|
javaCompileOptions.annotationProcessorOptions.arguments = [
|
||||||
"room.schemaLocation": "${qtAndroidDir}/schemas".toString()
|
"room.schemaLocation": "${qtAndroidDir}/schemas".toString()
|
||||||
|
|
|
@ -70,6 +70,15 @@ public class BadConfigException extends Exception {
|
||||||
EXCLUDED_APPLICATIONS("ExcludedApplications"),
|
EXCLUDED_APPLICATIONS("ExcludedApplications"),
|
||||||
INCLUDED_APPLICATIONS("IncludedApplications"),
|
INCLUDED_APPLICATIONS("IncludedApplications"),
|
||||||
LISTEN_PORT("ListenPort"),
|
LISTEN_PORT("ListenPort"),
|
||||||
|
JC("Jc"),
|
||||||
|
JMIN("Jmin"),
|
||||||
|
JMAX("Jmax"),
|
||||||
|
S1("S1"),
|
||||||
|
S2("S2"),
|
||||||
|
H1("H1"),
|
||||||
|
H2("H2"),
|
||||||
|
H3("H3"),
|
||||||
|
H4("H4"),
|
||||||
MTU("MTU"),
|
MTU("MTU"),
|
||||||
PERSISTENT_KEEPALIVE("PersistentKeepalive"),
|
PERSISTENT_KEEPALIVE("PersistentKeepalive"),
|
||||||
PRE_SHARED_KEY("PresharedKey"),
|
PRE_SHARED_KEY("PresharedKey"),
|
||||||
|
|
|
@ -44,6 +44,15 @@ public final class Interface {
|
||||||
private final KeyPair keyPair;
|
private final KeyPair keyPair;
|
||||||
private final Optional<Integer> listenPort;
|
private final Optional<Integer> listenPort;
|
||||||
private final Optional<Integer> mtu;
|
private final Optional<Integer> mtu;
|
||||||
|
private final Optional<Integer> jc;
|
||||||
|
private final Optional<Integer> jmin;
|
||||||
|
private final Optional<Integer> jmax;
|
||||||
|
private final Optional<Integer> s1;
|
||||||
|
private final Optional<Integer> s2;
|
||||||
|
private final Optional<Long> h1;
|
||||||
|
private final Optional<Long> h2;
|
||||||
|
private final Optional<Long> h3;
|
||||||
|
private final Optional<Long> h4;
|
||||||
|
|
||||||
private Interface(final Builder builder) {
|
private Interface(final Builder builder) {
|
||||||
// Defensively copy to ensure immutability even if the Builder is reused.
|
// Defensively copy to ensure immutability even if the Builder is reused.
|
||||||
|
@ -56,6 +65,15 @@ public final class Interface {
|
||||||
keyPair = Objects.requireNonNull(builder.keyPair, "Interfaces must have a private key");
|
keyPair = Objects.requireNonNull(builder.keyPair, "Interfaces must have a private key");
|
||||||
listenPort = builder.listenPort;
|
listenPort = builder.listenPort;
|
||||||
mtu = builder.mtu;
|
mtu = builder.mtu;
|
||||||
|
jc = builder.jc;
|
||||||
|
jmax = builder.jmax;
|
||||||
|
jmin = builder.jmin;
|
||||||
|
s1 = builder.s1;
|
||||||
|
s2 = builder.s2;
|
||||||
|
h1 = builder.h1;
|
||||||
|
h2 = builder.h2;
|
||||||
|
h3 = builder.h3;
|
||||||
|
h4 = builder.h4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +113,33 @@ public final class Interface {
|
||||||
case "privatekey":
|
case "privatekey":
|
||||||
builder.parsePrivateKey(attribute.getValue());
|
builder.parsePrivateKey(attribute.getValue());
|
||||||
break;
|
break;
|
||||||
|
case "jc":
|
||||||
|
builder.parseJc(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "jmin":
|
||||||
|
builder.parseJmin(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "jmax":
|
||||||
|
builder.parseJmax(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "s1":
|
||||||
|
builder.parseS1(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "s2":
|
||||||
|
builder.parseS2(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "h1":
|
||||||
|
builder.parseH1(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "h2":
|
||||||
|
builder.parseH2(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "h3":
|
||||||
|
builder.parseH3(attribute.getValue());
|
||||||
|
break;
|
||||||
|
case "h4":
|
||||||
|
builder.parseH4(attribute.getValue());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new BadConfigException(
|
throw new BadConfigException(
|
||||||
Section.INTERFACE, Location.TOP_LEVEL, Reason.UNKNOWN_ATTRIBUTE, attribute.getKey());
|
Section.INTERFACE, Location.TOP_LEVEL, Reason.UNKNOWN_ATTRIBUTE, attribute.getKey());
|
||||||
|
@ -111,7 +156,9 @@ public final class Interface {
|
||||||
return addresses.equals(other.addresses) && dnsServers.equals(other.dnsServers)
|
return addresses.equals(other.addresses) && dnsServers.equals(other.dnsServers)
|
||||||
&& excludedApplications.equals(other.excludedApplications)
|
&& excludedApplications.equals(other.excludedApplications)
|
||||||
&& includedApplications.equals(other.includedApplications) && keyPair.equals(other.keyPair)
|
&& includedApplications.equals(other.includedApplications) && keyPair.equals(other.keyPair)
|
||||||
&& listenPort.equals(other.listenPort) && mtu.equals(other.mtu);
|
&& listenPort.equals(other.listenPort) && mtu.equals(other.mtu) && jc.equals(other.jc) && jmin.equals(other.jmin)
|
||||||
|
&& jmax.equals(other.jmax) && s1.equals(other.s1) && s2.equals(other.s2) && h1.equals(other.h1) && h2.equals(other.h2)
|
||||||
|
&& h3.equals(other.h3) && h4.equals(other.h4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,6 +227,42 @@ public final class Interface {
|
||||||
public Optional<Integer> getMtu() {
|
public Optional<Integer> getMtu() {
|
||||||
return mtu;
|
return mtu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getJc() {
|
||||||
|
return jc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getJmin() {
|
||||||
|
return jmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getJmax() {
|
||||||
|
return jmax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getS1() {
|
||||||
|
return s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getS2() {
|
||||||
|
return s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Long> getH1() {
|
||||||
|
return h1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Long> getH2() {
|
||||||
|
return h2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Long> getH3() {
|
||||||
|
return h3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Long> getH4() {
|
||||||
|
return h4;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
@ -191,6 +274,15 @@ public final class Interface {
|
||||||
hash = 31 * hash + keyPair.hashCode();
|
hash = 31 * hash + keyPair.hashCode();
|
||||||
hash = 31 * hash + listenPort.hashCode();
|
hash = 31 * hash + listenPort.hashCode();
|
||||||
hash = 31 * hash + mtu.hashCode();
|
hash = 31 * hash + mtu.hashCode();
|
||||||
|
hash = 31 * hash + jc.hashCode();
|
||||||
|
hash = 31 * hash + jmin.hashCode();
|
||||||
|
hash = 31 * hash + jmax.hashCode();
|
||||||
|
hash = 31 * hash + s1.hashCode();
|
||||||
|
hash = 31 * hash + s2.hashCode();
|
||||||
|
hash = 31 * hash + h1.hashCode();
|
||||||
|
hash = 31 * hash + h2.hashCode();
|
||||||
|
hash = 31 * hash + h3.hashCode();
|
||||||
|
hash = 31 * hash + h4.hashCode();
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +326,19 @@ public final class Interface {
|
||||||
.append('\n');
|
.append('\n');
|
||||||
listenPort.ifPresent(lp -> sb.append("ListenPort = ").append(lp).append('\n'));
|
listenPort.ifPresent(lp -> sb.append("ListenPort = ").append(lp).append('\n'));
|
||||||
mtu.ifPresent(m -> sb.append("MTU = ").append(m).append('\n'));
|
mtu.ifPresent(m -> sb.append("MTU = ").append(m).append('\n'));
|
||||||
|
|
||||||
|
jc.ifPresent(t_jc -> sb.append("Jc = ").append(t_jc).append('\n'));
|
||||||
|
jmin.ifPresent(t_jmin -> sb.append("Jmin = ").append(t_jmin).append('\n'));
|
||||||
|
jmax.ifPresent(t_jmax -> sb.append("Jmax = ").append(t_jmax).append('\n'));
|
||||||
|
|
||||||
|
s1.ifPresent(t_s1 -> sb.append("S1 = ").append(t_s1).append('\n'));
|
||||||
|
s2.ifPresent(t_s2 -> sb.append("S2 = ").append(t_s2).append('\n'));
|
||||||
|
|
||||||
|
h1.ifPresent(t_h1 -> sb.append("H1 = ").append(t_h1).append('\n'));
|
||||||
|
h2.ifPresent(t_h2 -> sb.append("H2 = ").append(t_h2).append('\n'));
|
||||||
|
h3.ifPresent(t_h3 -> sb.append("H3 = ").append(t_h3).append('\n'));
|
||||||
|
h4.ifPresent(t_h4 -> sb.append("H4 = ").append(t_h4).append('\n'));
|
||||||
|
|
||||||
sb.append("PrivateKey = ").append(keyPair.getPrivateKey().toBase64()).append('\n');
|
sb.append("PrivateKey = ").append(keyPair.getPrivateKey().toBase64()).append('\n');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -248,6 +353,18 @@ public final class Interface {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("private_key=").append(keyPair.getPrivateKey().toHex()).append('\n');
|
sb.append("private_key=").append(keyPair.getPrivateKey().toHex()).append('\n');
|
||||||
listenPort.ifPresent(lp -> sb.append("listen_port=").append(lp).append('\n'));
|
listenPort.ifPresent(lp -> sb.append("listen_port=").append(lp).append('\n'));
|
||||||
|
|
||||||
|
jc.ifPresent(t_jc -> sb.append("jc=").append(t_jc).append('\n'));
|
||||||
|
jmin.ifPresent(t_jmin -> sb.append("jmin=").append(t_jmin).append('\n'));
|
||||||
|
jmax.ifPresent(t_jmax -> sb.append("jmax=").append(t_jmax).append('\n'));
|
||||||
|
|
||||||
|
s1.ifPresent(t_s1 -> sb.append("s1=").append(t_s1).append('\n'));
|
||||||
|
s2.ifPresent(t_s2 -> sb.append("s2=").append(t_s2).append('\n'));
|
||||||
|
|
||||||
|
h1.ifPresent(t_h1 -> sb.append("h1=").append(t_h1).append('\n'));
|
||||||
|
h2.ifPresent(t_h2 -> sb.append("h2=").append(t_h2).append('\n'));
|
||||||
|
h3.ifPresent(t_h3 -> sb.append("h3=").append(t_h3).append('\n'));
|
||||||
|
h4.ifPresent(t_h4 -> sb.append("h4=").append(t_h4).append('\n'));
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,6 +384,17 @@ public final class Interface {
|
||||||
private Optional<Integer> listenPort = Optional.empty();
|
private Optional<Integer> listenPort = Optional.empty();
|
||||||
// Defaults to not present.
|
// Defaults to not present.
|
||||||
private Optional<Integer> mtu = Optional.empty();
|
private Optional<Integer> mtu = Optional.empty();
|
||||||
|
private Optional<Integer> jc = Optional.empty();
|
||||||
|
private Optional<Integer> jmin = Optional.empty();
|
||||||
|
private Optional<Integer> jmax = Optional.empty();
|
||||||
|
|
||||||
|
private Optional<Integer> s1 = Optional.empty();
|
||||||
|
private Optional<Integer> s2 = Optional.empty();
|
||||||
|
|
||||||
|
private Optional<Long> h1 = Optional.empty();
|
||||||
|
private Optional<Long> h2 = Optional.empty();
|
||||||
|
private Optional<Long> h3 = Optional.empty();
|
||||||
|
private Optional<Long> h4 = Optional.empty();
|
||||||
|
|
||||||
public Builder addAddress(final InetNetwork address) {
|
public Builder addAddress(final InetNetwork address) {
|
||||||
addresses.add(address);
|
addresses.add(address);
|
||||||
|
@ -362,6 +490,78 @@ public final class Interface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder parseJc(final String jc) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setJc(Integer.parseInt(jc));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.JC, jc, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseJmax(final String jmax) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setJmax(Integer.parseInt(jmax));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.JMAX, jmax, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseJmin(final String jmin) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setJmin(Integer.parseInt(jmin));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.JMIN, jmin, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseS1(final String s1) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setS1(Integer.parseInt(s1));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.S1, s1, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseS2(final String s2) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setS2(Integer.parseInt(s2));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.S2, s2, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseH1(final String h1) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setH1(Long.parseLong(h1));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.H1, h1, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseH2(final String h2) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setH2(Long.parseLong(h2));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.H2, h2, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseH3(final String h3) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setH3(Long.parseLong(h3));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.H3, h3, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder parseH4(final String h4) throws BadConfigException {
|
||||||
|
try {
|
||||||
|
return setH4(Long.parseLong(h4));
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
throw new BadConfigException(Section.INTERFACE, Location.H4, h4, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Builder parsePrivateKey(final String privateKey) throws BadConfigException {
|
public Builder parsePrivateKey(final String privateKey) throws BadConfigException {
|
||||||
try {
|
try {
|
||||||
return setKeyPair(new KeyPair(Key.fromBase64(privateKey)));
|
return setKeyPair(new KeyPair(Key.fromBase64(privateKey)));
|
||||||
|
@ -386,9 +586,81 @@ public final class Interface {
|
||||||
public Builder setMtu(final int mtu) throws BadConfigException {
|
public Builder setMtu(final int mtu) throws BadConfigException {
|
||||||
if (mtu < 0)
|
if (mtu < 0)
|
||||||
throw new BadConfigException(
|
throw new BadConfigException(
|
||||||
Section.INTERFACE, Location.LISTEN_PORT, Reason.INVALID_VALUE, String.valueOf(mtu));
|
Section.INTERFACE, Location.MTU, Reason.INVALID_VALUE, String.valueOf(mtu));
|
||||||
this.mtu = mtu == 0 ? Optional.empty() : Optional.of(mtu);
|
this.mtu = mtu == 0 ? Optional.empty() : Optional.of(mtu);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setJc(final int jc) throws BadConfigException {
|
||||||
|
if (jc < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.JC, Reason.INVALID_VALUE, String.valueOf(jc));
|
||||||
|
this.jc = Optional.of(jc);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setJmin(final int jmin) throws BadConfigException {
|
||||||
|
if (jmin < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.JMIN, Reason.INVALID_VALUE, String.valueOf(jmin));
|
||||||
|
this.jmin = Optional.of(jmin);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setJmax(final int jmax) throws BadConfigException {
|
||||||
|
if (jmax < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.JMAX, Reason.INVALID_VALUE, String.valueOf(jmax));
|
||||||
|
this.jmax = Optional.of(jmax);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setS1(final int s1) throws BadConfigException {
|
||||||
|
if (s1 < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.S1, Reason.INVALID_VALUE, String.valueOf(s1));
|
||||||
|
this.s1 = Optional.of(s1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setS2(final int s2) throws BadConfigException {
|
||||||
|
if (s2 < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.S2, Reason.INVALID_VALUE, String.valueOf(s2));
|
||||||
|
this.s2 = Optional.of(s2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setH1(final long h1) throws BadConfigException {
|
||||||
|
if (h1 < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.H1, Reason.INVALID_VALUE, String.valueOf(h1));
|
||||||
|
this.h1 = Optional.of(h1);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setH2(final long h2) throws BadConfigException {
|
||||||
|
if (h2 < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.H2, Reason.INVALID_VALUE, String.valueOf(h2));
|
||||||
|
this.h2 = Optional.of(h2);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setH3(final long h3) throws BadConfigException {
|
||||||
|
if (h3 < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.H3, Reason.INVALID_VALUE, String.valueOf(h3));
|
||||||
|
this.h3 = Optional.of(h3);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setH4(final long h4) throws BadConfigException {
|
||||||
|
if (h4 < 0)
|
||||||
|
throw new BadConfigException(
|
||||||
|
Section.INTERFACE, Location.H4, Reason.INVALID_VALUE, String.valueOf(h4));
|
||||||
|
this.h4 = Optional.of(h4);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,7 +380,10 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
||||||
mNetworkState.bindNetworkListener()
|
mNetworkState.bindNetworkListener()
|
||||||
}
|
}
|
||||||
"wireguard" -> {
|
"wireguard" -> {
|
||||||
startWireGuard()
|
startWireGuard("wireguard")
|
||||||
|
}
|
||||||
|
"awg" -> {
|
||||||
|
startWireGuard("awg")
|
||||||
}
|
}
|
||||||
"shadowsocks" -> {
|
"shadowsocks" -> {
|
||||||
startShadowsocks()
|
startShadowsocks()
|
||||||
|
@ -457,7 +460,8 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
||||||
fun turnOff() {
|
fun turnOff() {
|
||||||
Log.v(tag, "Aman: turnOff....................")
|
Log.v(tag, "Aman: turnOff....................")
|
||||||
when (mProtocol) {
|
when (mProtocol) {
|
||||||
"wireguard" -> {
|
"wireguard",
|
||||||
|
"awg" -> {
|
||||||
GoBackend.wgTurnOff(currentTunnelHandle)
|
GoBackend.wgTurnOff(currentTunnelHandle)
|
||||||
}
|
}
|
||||||
"cloak",
|
"cloak",
|
||||||
|
@ -559,14 +563,14 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
||||||
}
|
}
|
||||||
return parseData
|
return parseData
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Wireguard [Config] from a [json] string -
|
* Create a Wireguard [Config] from a [json] string -
|
||||||
* The [json] will be created in AndroidVpnProtocol.cpp
|
* The [json] will be created in AndroidVpnProtocol.cpp
|
||||||
*/
|
*/
|
||||||
private fun buildWireguardConfig(obj: JSONObject): Config {
|
private fun buildWireguardConfig(obj: JSONObject, type: String): Config {
|
||||||
val confBuilder = Config.Builder()
|
val confBuilder = Config.Builder()
|
||||||
val wireguardConfigData = obj.getJSONObject("wireguard_config_data")
|
val wireguardConfigData = obj.getJSONObject(type)
|
||||||
val config = parseConfigData(wireguardConfigData.getString("config"))
|
val config = parseConfigData(wireguardConfigData.getString("config"))
|
||||||
val peerBuilder = Peer.Builder()
|
val peerBuilder = Peer.Builder()
|
||||||
val peerConfig = config["Peer"]!!
|
val peerConfig = config["Peer"]!!
|
||||||
|
@ -599,6 +603,30 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
||||||
ifaceConfig["DNS"]!!.split(",").forEach {
|
ifaceConfig["DNS"]!!.split(",").forEach {
|
||||||
ifaceBuilder.addDnsServer(InetNetwork.parse(it.trim()).address)
|
ifaceBuilder.addDnsServer(InetNetwork.parse(it.trim()).address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ifaceBuilder.parsePrivateKey(ifaceConfig["PrivateKey"])
|
||||||
|
if (type == "awg_config_data") {
|
||||||
|
ifaceBuilder.parseJc(ifaceConfig["Jc"])
|
||||||
|
ifaceBuilder.parseJmin(ifaceConfig["Jmin"])
|
||||||
|
ifaceBuilder.parseJmax(ifaceConfig["Jmax"])
|
||||||
|
ifaceBuilder.parseS1(ifaceConfig["S1"])
|
||||||
|
ifaceBuilder.parseS2(ifaceConfig["S2"])
|
||||||
|
ifaceBuilder.parseH1(ifaceConfig["H1"])
|
||||||
|
ifaceBuilder.parseH2(ifaceConfig["H2"])
|
||||||
|
ifaceBuilder.parseH3(ifaceConfig["H3"])
|
||||||
|
ifaceBuilder.parseH4(ifaceConfig["H4"])
|
||||||
|
} else {
|
||||||
|
ifaceBuilder.parseJc("0")
|
||||||
|
ifaceBuilder.parseJmin("0")
|
||||||
|
ifaceBuilder.parseJmax("0")
|
||||||
|
ifaceBuilder.parseS1("0")
|
||||||
|
ifaceBuilder.parseS2("0")
|
||||||
|
ifaceBuilder.parseH1("0")
|
||||||
|
ifaceBuilder.parseH2("0")
|
||||||
|
ifaceBuilder.parseH3("0")
|
||||||
|
ifaceBuilder.parseH4("0")
|
||||||
|
|
||||||
|
}
|
||||||
/*val jExcludedApplication = obj.getJSONArray("excludedApps")
|
/*val jExcludedApplication = obj.getJSONArray("excludedApps")
|
||||||
(0 until jExcludedApplication.length()).toList().forEach {
|
(0 until jExcludedApplication.length()).toList().forEach {
|
||||||
val appName = jExcludedApplication.get(it).toString()
|
val appName = jExcludedApplication.get(it).toString()
|
||||||
|
@ -716,8 +744,8 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startWireGuard() {
|
private fun startWireGuard(type: String) {
|
||||||
val wireguard_conf = buildWireguardConfig(mConfig!!)
|
val wireguard_conf = buildWireguardConfig(mConfig!!, type + "_config_data")
|
||||||
Log.i(tag, "startWireGuard: wireguard_conf : $wireguard_conf")
|
Log.i(tag, "startWireGuard: wireguard_conf : $wireguard_conf")
|
||||||
if (currentTunnelHandle != -1) {
|
if (currentTunnelHandle != -1) {
|
||||||
Log.e(tag, "Tunnel already up")
|
Log.e(tag, "Tunnel already up")
|
||||||
|
@ -728,9 +756,15 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
||||||
val builder = Builder()
|
val builder = Builder()
|
||||||
setupBuilder(wireguard_conf, builder)
|
setupBuilder(wireguard_conf, builder)
|
||||||
builder.setSession("Amnezia")
|
builder.setSession("Amnezia")
|
||||||
|
|
||||||
|
|
||||||
builder.establish().use { tun ->
|
builder.establish().use { tun ->
|
||||||
if (tun == null) return
|
if (tun == null) return
|
||||||
currentTunnelHandle = GoBackend.wgTurnOn("Amnezia", tun.detachFd(), wgConfig)
|
if (type == "awg"){
|
||||||
|
currentTunnelHandle = GoBackend.wgTurnOn("awg0", tun.detachFd(), wgConfig)
|
||||||
|
} else {
|
||||||
|
currentTunnelHandle = GoBackend.wgTurnOn("amn0", tun.detachFd(), wgConfig)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (currentTunnelHandle < 0) {
|
if (currentTunnelHandle < 0) {
|
||||||
Log.e(tag, "Activation Error Code -> $currentTunnelHandle")
|
Log.e(tag, "Activation Error Code -> $currentTunnelHandle")
|
||||||
|
|
|
@ -97,7 +97,7 @@ target_compile_options(${PROJECT} PRIVATE
|
||||||
-DVPN_NE_BUNDLEID=\"${BUILD_IOS_APP_IDENTIFIER}.network-extension\"
|
-DVPN_NE_BUNDLEID=\"${BUILD_IOS_APP_IDENTIFIER}.network-extension\"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(WG_APPLE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/wireguard-apple/Sources)
|
set(WG_APPLE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/awg-apple/Sources)
|
||||||
|
|
||||||
target_sources(${PROJECT} PRIVATE
|
target_sources(${PROJECT} PRIVATE
|
||||||
# ${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosvpnprotocol.swift
|
# ${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosvpnprotocol.swift
|
||||||
|
|
59
client/configurators/awg_configurator.cpp
Normal file
59
client/configurators/awg_configurator.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#include "awg_configurator.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
#include "core/servercontroller.h"
|
||||||
|
|
||||||
|
AwgConfigurator::AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
|
: WireguardConfigurator(settings, true, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AwgConfigurator::genAwgConfig(const ServerCredentials &credentials,
|
||||||
|
DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
|
{
|
||||||
|
QString config = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
|
QJsonObject jsonConfig = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||||
|
|
||||||
|
ServerController serverController(m_settings);
|
||||||
|
QString serverConfig = serverController.getTextFileFromContainer(container, credentials, protocols::awg::serverConfigPath, errorCode);
|
||||||
|
|
||||||
|
QMap<QString, QString> serverConfigMap;
|
||||||
|
auto serverConfigLines = serverConfig.split("\n");
|
||||||
|
for (auto &line : serverConfigLines) {
|
||||||
|
auto trimmedLine = line.trimmed();
|
||||||
|
if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
QStringList parts = trimmedLine.split(" = ");
|
||||||
|
if (parts.count() == 2) {
|
||||||
|
serverConfigMap.insert(parts[0].trimmed(), parts[1].trimmed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.replace("$JUNK_PACKET_COUNT", serverConfigMap.value(config_key::junkPacketCount));
|
||||||
|
config.replace("$JUNK_PACKET_MIN_SIZE", serverConfigMap.value(config_key::junkPacketMinSize));
|
||||||
|
config.replace("$JUNK_PACKET_MAX_SIZE", serverConfigMap.value(config_key::junkPacketMaxSize));
|
||||||
|
config.replace("$INIT_PACKET_JUNK_SIZE", serverConfigMap.value(config_key::initPacketJunkSize));
|
||||||
|
config.replace("$RESPONSE_PACKET_JUNK_SIZE", serverConfigMap.value(config_key::responsePacketJunkSize));
|
||||||
|
config.replace("$INIT_PACKET_MAGIC_HEADER", serverConfigMap.value(config_key::initPacketMagicHeader));
|
||||||
|
config.replace("$RESPONSE_PACKET_MAGIC_HEADER", serverConfigMap.value(config_key::responsePacketMagicHeader));
|
||||||
|
config.replace("$UNDERLOAD_PACKET_MAGIC_HEADER", serverConfigMap.value(config_key::underloadPacketMagicHeader));
|
||||||
|
config.replace("$TRANSPORT_PACKET_MAGIC_HEADER", serverConfigMap.value(config_key::transportPacketMagicHeader));
|
||||||
|
|
||||||
|
jsonConfig[config_key::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
|
||||||
|
jsonConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
|
||||||
|
jsonConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
|
||||||
|
jsonConfig[config_key::initPacketJunkSize] = serverConfigMap.value(config_key::initPacketJunkSize);
|
||||||
|
jsonConfig[config_key::responsePacketJunkSize] = serverConfigMap.value(config_key::responsePacketJunkSize);
|
||||||
|
jsonConfig[config_key::initPacketMagicHeader] = serverConfigMap.value(config_key::initPacketMagicHeader);
|
||||||
|
jsonConfig[config_key::responsePacketMagicHeader] = serverConfigMap.value(config_key::responsePacketMagicHeader);
|
||||||
|
jsonConfig[config_key::underloadPacketMagicHeader] = serverConfigMap.value(config_key::underloadPacketMagicHeader);
|
||||||
|
jsonConfig[config_key::transportPacketMagicHeader] = serverConfigMap.value(config_key::transportPacketMagicHeader);
|
||||||
|
|
||||||
|
return QJsonDocument(jsonConfig).toJson();
|
||||||
|
}
|
18
client/configurators/awg_configurator.h
Normal file
18
client/configurators/awg_configurator.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef AWGCONFIGURATOR_H
|
||||||
|
#define AWGCONFIGURATOR_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "wireguard_configurator.h"
|
||||||
|
|
||||||
|
class AwgConfigurator : public WireguardConfigurator
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AwgConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QString genAwgConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AWGCONFIGURATOR_H
|
|
@ -1,32 +1,34 @@
|
||||||
#include "vpn_configurator.h"
|
#include "vpn_configurator.h"
|
||||||
#include "openvpn_configurator.h"
|
|
||||||
#include "cloak_configurator.h"
|
#include "cloak_configurator.h"
|
||||||
#include "shadowsocks_configurator.h"
|
|
||||||
#include "wireguard_configurator.h"
|
|
||||||
#include "ikev2_configurator.h"
|
#include "ikev2_configurator.h"
|
||||||
|
#include "openvpn_configurator.h"
|
||||||
|
#include "shadowsocks_configurator.h"
|
||||||
#include "ssh_configurator.h"
|
#include "ssh_configurator.h"
|
||||||
|
#include "wireguard_configurator.h"
|
||||||
|
#include "awg_configurator.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "utilities.h"
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "utilities.h"
|
||||||
|
|
||||||
VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent):
|
VpnConfigurator::VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
ConfiguratorBase(settings, parent)
|
: ConfiguratorBase(settings, parent)
|
||||||
{
|
{
|
||||||
openVpnConfigurator = std::shared_ptr<OpenVpnConfigurator>(new OpenVpnConfigurator(settings, this));
|
openVpnConfigurator = std::shared_ptr<OpenVpnConfigurator>(new OpenVpnConfigurator(settings, this));
|
||||||
shadowSocksConfigurator = std::shared_ptr<ShadowSocksConfigurator>(new ShadowSocksConfigurator(settings, this));
|
shadowSocksConfigurator = std::shared_ptr<ShadowSocksConfigurator>(new ShadowSocksConfigurator(settings, this));
|
||||||
cloakConfigurator = std::shared_ptr<CloakConfigurator>(new CloakConfigurator(settings, this));
|
cloakConfigurator = std::shared_ptr<CloakConfigurator>(new CloakConfigurator(settings, this));
|
||||||
wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, this));
|
wireguardConfigurator = std::shared_ptr<WireguardConfigurator>(new WireguardConfigurator(settings, false, this));
|
||||||
ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, this));
|
ikev2Configurator = std::shared_ptr<Ikev2Configurator>(new Ikev2Configurator(settings, this));
|
||||||
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, this));
|
sshConfigurator = std::shared_ptr<SshConfigurator>(new SshConfigurator(settings, this));
|
||||||
|
awgConfigurator = std::shared_ptr<AwgConfigurator>(new AwgConfigurator(settings, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
|
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
switch (proto) {
|
switch (proto) {
|
||||||
case Proto::OpenVpn:
|
case Proto::OpenVpn:
|
||||||
|
@ -35,17 +37,17 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
|
||||||
case Proto::ShadowSocks:
|
case Proto::ShadowSocks:
|
||||||
return shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
return shadowSocksConfigurator->genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Proto::Cloak:
|
case Proto::Cloak: return cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
|
||||||
return cloakConfigurator->genCloakConfig(credentials, container, containerConfig, errorCode);
|
|
||||||
|
|
||||||
case Proto::WireGuard:
|
case Proto::WireGuard:
|
||||||
return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, errorCode);
|
return wireguardConfigurator->genWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Proto::Ikev2:
|
case Proto::Awg:
|
||||||
return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
|
return awgConfigurator->genAwgConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
default:
|
case Proto::Ikev2: return ikev2Configurator->genIkev2Config(credentials, container, containerConfig, errorCode);
|
||||||
return "";
|
|
||||||
|
default: return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +64,8 @@ QPair<QString, QString> VpnConfigurator::getDnsForConfig(int serverIndex)
|
||||||
if (dns.first.isEmpty() || !Utils::checkIPv4Format(dns.first)) {
|
if (dns.first.isEmpty() || !Utils::checkIPv4Format(dns.first)) {
|
||||||
if (useAmneziaDns && m_settings->containers(serverIndex).contains(DockerContainer::Dns)) {
|
if (useAmneziaDns && m_settings->containers(serverIndex).contains(DockerContainer::Dns)) {
|
||||||
dns.first = protocols::dns::amneziaDnsIp;
|
dns.first = protocols::dns::amneziaDnsIp;
|
||||||
}
|
} else
|
||||||
else dns.first = m_settings->primaryDns();
|
dns.first = m_settings->primaryDns();
|
||||||
}
|
}
|
||||||
if (dns.second.isEmpty() || !Utils::checkIPv4Format(dns.second)) {
|
if (dns.second.isEmpty() || !Utils::checkIPv4Format(dns.second)) {
|
||||||
dns.second = m_settings->secondaryDns();
|
dns.second = m_settings->secondaryDns();
|
||||||
|
@ -73,8 +75,8 @@ QPair<QString, QString> VpnConfigurator::getDnsForConfig(int serverIndex)
|
||||||
return dns;
|
return dns;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithDnsSettings(int serverIndex, DockerContainer container,
|
QString &VpnConfigurator::processConfigWithDnsSettings(int serverIndex, DockerContainer container, Proto proto,
|
||||||
Proto proto, QString &config)
|
QString &config)
|
||||||
{
|
{
|
||||||
auto dns = getDnsForConfig(serverIndex);
|
auto dns = getDnsForConfig(serverIndex);
|
||||||
|
|
||||||
|
@ -84,8 +86,8 @@ QString &VpnConfigurator::processConfigWithDnsSettings(int serverIndex, DockerCo
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, DockerContainer container,
|
QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, DockerContainer container, Proto proto,
|
||||||
Proto proto, QString &config)
|
QString &config)
|
||||||
{
|
{
|
||||||
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
||||||
|
|
||||||
|
@ -95,8 +97,8 @@ QString &VpnConfigurator::processConfigWithLocalSettings(int serverIndex, Docker
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, DockerContainer container,
|
QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, DockerContainer container, Proto proto,
|
||||||
Proto proto, QString &config)
|
QString &config)
|
||||||
{
|
{
|
||||||
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
processConfigWithDnsSettings(serverIndex, container, proto, config);
|
||||||
|
|
||||||
|
@ -107,7 +109,7 @@ QString &VpnConfigurator::processConfigWithExportSettings(int serverIndex, Docke
|
||||||
}
|
}
|
||||||
|
|
||||||
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
||||||
const QString &stdOut)
|
const QString &stdOut)
|
||||||
{
|
{
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
|
|
|
@ -13,13 +13,14 @@ class CloakConfigurator;
|
||||||
class WireguardConfigurator;
|
class WireguardConfigurator;
|
||||||
class Ikev2Configurator;
|
class Ikev2Configurator;
|
||||||
class SshConfigurator;
|
class SshConfigurator;
|
||||||
|
class AwgConfigurator;
|
||||||
|
|
||||||
// Retrieve connection settings from server
|
// Retrieve connection settings from server
|
||||||
class VpnConfigurator : ConfiguratorBase
|
class VpnConfigurator : ConfiguratorBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
explicit VpnConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
|
||||||
QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
|
||||||
|
@ -40,6 +41,7 @@ public:
|
||||||
std::shared_ptr<WireguardConfigurator> wireguardConfigurator;
|
std::shared_ptr<WireguardConfigurator> wireguardConfigurator;
|
||||||
std::shared_ptr<Ikev2Configurator> ikev2Configurator;
|
std::shared_ptr<Ikev2Configurator> ikev2Configurator;
|
||||||
std::shared_ptr<SshConfigurator> sshConfigurator;
|
std::shared_ptr<SshConfigurator> sshConfigurator;
|
||||||
|
std::shared_ptr<AwgConfigurator> awgConfigurator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VPN_CONFIGURATOR_H
|
#endif // VPN_CONFIGURATOR_H
|
||||||
|
|
|
@ -19,9 +19,20 @@
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, QObject *parent)
|
WireguardConfigurator::WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent)
|
||||||
: ConfiguratorBase(settings, parent)
|
: ConfiguratorBase(settings, parent), m_isAwg(isAwg)
|
||||||
{
|
{
|
||||||
|
m_serverConfigPath = m_isAwg ? amnezia::protocols::awg::serverConfigPath
|
||||||
|
: amnezia::protocols::wireguard::serverConfigPath;
|
||||||
|
m_serverPublicKeyPath = m_isAwg ? amnezia::protocols::awg::serverPublicKeyPath
|
||||||
|
: amnezia::protocols::wireguard::serverPublicKeyPath;
|
||||||
|
m_serverPskKeyPath = m_isAwg ? amnezia::protocols::awg::serverPskKeyPath
|
||||||
|
: amnezia::protocols::wireguard::serverPskKeyPath;
|
||||||
|
m_configTemplate = m_isAwg ? ProtocolScriptType::awg_template
|
||||||
|
: ProtocolScriptType::wireguard_template;
|
||||||
|
|
||||||
|
m_protocolName = m_isAwg ? config_key::awg : config_key::wireguard;
|
||||||
|
m_defaultPort = m_isAwg ? protocols::wireguard::defaultPort : protocols::awg::defaultPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
WireguardConfigurator::ConnectionData WireguardConfigurator::genClientKeys()
|
||||||
|
@ -62,7 +73,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
{
|
{
|
||||||
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
WireguardConfigurator::ConnectionData connData = WireguardConfigurator::genClientKeys();
|
||||||
connData.host = credentials.hostName;
|
connData.host = credentials.hostName;
|
||||||
connData.port = containerConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
|
connData.port = containerConfig.value(m_protocolName).toObject().value(config_key::port).toString(m_defaultPort);
|
||||||
|
|
||||||
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
if (connData.clientPrivKey.isEmpty() || connData.clientPubKey.isEmpty()) {
|
||||||
if (errorCode)
|
if (errorCode)
|
||||||
|
@ -76,7 +87,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
// Get list of already created clients (only IP addresses)
|
// Get list of already created clients (only IP addresses)
|
||||||
QString nextIpNumber;
|
QString nextIpNumber;
|
||||||
{
|
{
|
||||||
QString script = QString("cat %1 | grep AllowedIPs").arg(amnezia::protocols::wireguard::serverConfigPath);
|
QString script = QString("cat %1 | grep AllowedIPs").arg(m_serverConfigPath);
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
stdOut += data + "\n";
|
stdOut += data + "\n";
|
||||||
|
@ -123,8 +134,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get keys
|
// Get keys
|
||||||
connData.serverPubKey = serverController.getTextFileFromContainer(
|
connData.serverPubKey = serverController.getTextFileFromContainer(container, credentials, m_serverPublicKeyPath, &e);
|
||||||
container, credentials, amnezia::protocols::wireguard::serverPublicKeyPath, &e);
|
|
||||||
connData.serverPubKey.replace("\n", "");
|
connData.serverPubKey.replace("\n", "");
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode)
|
if (errorCode)
|
||||||
|
@ -132,8 +142,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
connData.pskKey = serverController.getTextFileFromContainer(container, credentials,
|
connData.pskKey = serverController.getTextFileFromContainer(container, credentials, m_serverPskKeyPath, &e);
|
||||||
amnezia::protocols::wireguard::serverPskKeyPath, &e);
|
|
||||||
connData.pskKey.replace("\n", "");
|
connData.pskKey.replace("\n", "");
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
|
@ -147,12 +156,9 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
"PublicKey = %1\n"
|
"PublicKey = %1\n"
|
||||||
"PresharedKey = %2\n"
|
"PresharedKey = %2\n"
|
||||||
"AllowedIPs = %3/32\n\n")
|
"AllowedIPs = %3/32\n\n")
|
||||||
.arg(connData.clientPubKey)
|
.arg(connData.clientPubKey, connData.pskKey, connData.clientIP);
|
||||||
.arg(connData.pskKey)
|
|
||||||
.arg(connData.clientIP);
|
|
||||||
|
|
||||||
e = serverController.uploadTextFileToContainer(container, credentials, configPart,
|
e = serverController.uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
|
||||||
protocols::wireguard::serverConfigPath,
|
|
||||||
libssh::SftpOverwriteMode::SftpAppendToExisting);
|
libssh::SftpOverwriteMode::SftpAppendToExisting);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
|
@ -161,11 +167,11 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString script = QString("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick strip %1)'")
|
||||||
|
.arg(m_serverConfigPath);
|
||||||
|
|
||||||
e = serverController.runScript(
|
e = serverController.runScript(
|
||||||
credentials,
|
credentials, serverController.replaceVars(script, serverController.genVarsForScript(credentials, container)));
|
||||||
serverController.replaceVars("sudo docker exec -i $CONTAINER_NAME bash -c 'wg syncconf wg0 <(wg-quick "
|
|
||||||
"strip /opt/amnezia/wireguard/wg0.conf)'",
|
|
||||||
serverController.genVarsForScript(credentials, container)));
|
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
}
|
}
|
||||||
|
@ -174,9 +180,9 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
const QJsonObject &containerConfig, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ServerController serverController(m_settings);
|
ServerController serverController(m_settings);
|
||||||
QString config =
|
QString scriptData = amnezia::scriptData(m_configTemplate, container);
|
||||||
serverController.replaceVars(amnezia::scriptData(ProtocolScriptType::wireguard_template, container),
|
QString config = serverController.replaceVars(
|
||||||
serverController.genVarsForScript(credentials, container, containerConfig));
|
scriptData, serverController.genVarsForScript(credentials, container, containerConfig));
|
||||||
|
|
||||||
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
|
ConnectionData connData = prepareWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||||
if (errorCode && *errorCode) {
|
if (errorCode && *errorCode) {
|
||||||
|
|
|
@ -6,35 +6,44 @@
|
||||||
|
|
||||||
#include "configurator_base.h"
|
#include "configurator_base.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
#include "core/scripts_registry.h"
|
||||||
|
|
||||||
class WireguardConfigurator : ConfiguratorBase
|
class WireguardConfigurator : public ConfiguratorBase
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
WireguardConfigurator(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
WireguardConfigurator(std::shared_ptr<Settings> settings, bool isAwg, QObject *parent = nullptr);
|
||||||
|
|
||||||
struct ConnectionData {
|
struct ConnectionData
|
||||||
|
{
|
||||||
QString clientPrivKey; // client private key
|
QString clientPrivKey; // client private key
|
||||||
QString clientPubKey; // client public key
|
QString clientPubKey; // client public key
|
||||||
QString clientIP; // internal client IP address
|
QString clientIP; // internal client IP address
|
||||||
QString serverPubKey; // tls-auth key
|
QString serverPubKey; // tls-auth key
|
||||||
QString pskKey; // preshared key
|
QString pskKey; // preshared key
|
||||||
QString host; // host ip
|
QString host; // host ip
|
||||||
QString port;
|
QString port;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
QString genWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
QString processConfigWithLocalSettings(QString config);
|
QString processConfigWithLocalSettings(QString config);
|
||||||
QString processConfigWithExportSettings(QString config);
|
QString processConfigWithExportSettings(QString config);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials,
|
ConnectionData prepareWireguardConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
ConnectionData genClientKeys();
|
ConnectionData genClientKeys();
|
||||||
|
|
||||||
|
bool m_isAwg;
|
||||||
|
QString m_serverConfigPath;
|
||||||
|
QString m_serverPublicKeyPath;
|
||||||
|
QString m_serverPskKeyPath;
|
||||||
|
amnezia::ProtocolScriptType m_configTemplate;
|
||||||
|
QString m_protocolName;
|
||||||
|
QString m_defaultPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WIREGUARD_CONFIGURATOR_H
|
#endif // WIREGUARD_CONFIGURATOR_H
|
||||||
|
|
|
@ -84,6 +84,7 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
|
||||||
{ DockerContainer::ShadowSocks, "ShadowSocks" },
|
{ DockerContainer::ShadowSocks, "ShadowSocks" },
|
||||||
{ DockerContainer::Cloak, "OpenVPN over Cloak" },
|
{ DockerContainer::Cloak, "OpenVPN over Cloak" },
|
||||||
{ DockerContainer::WireGuard, "WireGuard" },
|
{ DockerContainer::WireGuard, "WireGuard" },
|
||||||
|
{ DockerContainer::Awg, "AmneziaWG" },
|
||||||
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
||||||
|
|
||||||
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
||||||
|
@ -107,6 +108,9 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
|
||||||
{ DockerContainer::WireGuard,
|
{ DockerContainer::WireGuard,
|
||||||
QObject::tr("WireGuard - New popular VPN protocol with high performance, high speed and low power "
|
QObject::tr("WireGuard - New popular VPN protocol with high performance, high speed and low power "
|
||||||
"consumption. Recommended for regions with low levels of censorship.") },
|
"consumption. Recommended for regions with low levels of censorship.") },
|
||||||
|
{ DockerContainer::Awg,
|
||||||
|
QObject::tr("AmneziaWG - Special protocol from Amnezia, based on WireGuard. It's fast like WireGuard, but very resistant to blockages. "
|
||||||
|
"Recommended for regions with high levels of censorship.") },
|
||||||
{ DockerContainer::Ipsec,
|
{ DockerContainer::Ipsec,
|
||||||
QObject::tr("IKEv2 - Modern stable protocol, a bit faster than others, restores connection after "
|
QObject::tr("IKEv2 - Modern stable protocol, a bit faster than others, restores connection after "
|
||||||
"signal loss. It has native support on the latest versions of Android and iOS.") },
|
"signal loss. It has native support on the latest versions of Android and iOS.") },
|
||||||
|
@ -127,6 +131,7 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||||
QObject::tr("Container with OpenVpn and ShadowSocks protocols "
|
QObject::tr("Container with OpenVpn and ShadowSocks protocols "
|
||||||
"configured with traffic masking by Cloak plugin") },
|
"configured with traffic masking by Cloak plugin") },
|
||||||
{ DockerContainer::WireGuard, QObject::tr("WireGuard container") },
|
{ DockerContainer::WireGuard, QObject::tr("WireGuard container") },
|
||||||
|
{ DockerContainer::WireGuard, QObject::tr("AmneziaWG container") },
|
||||||
{ DockerContainer::Ipsec, QObject::tr("IPsec container") },
|
{ DockerContainer::Ipsec, QObject::tr("IPsec container") },
|
||||||
|
|
||||||
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
||||||
|
@ -143,6 +148,7 @@ amnezia::ServiceType ContainerProps::containerService(DockerContainer c)
|
||||||
case DockerContainer::Cloak: return ServiceType::Vpn;
|
case DockerContainer::Cloak: return ServiceType::Vpn;
|
||||||
case DockerContainer::ShadowSocks: return ServiceType::Vpn;
|
case DockerContainer::ShadowSocks: return ServiceType::Vpn;
|
||||||
case DockerContainer::WireGuard: return ServiceType::Vpn;
|
case DockerContainer::WireGuard: return ServiceType::Vpn;
|
||||||
|
case DockerContainer::Awg: return ServiceType::Vpn;
|
||||||
case DockerContainer::Ipsec: return ServiceType::Vpn;
|
case DockerContainer::Ipsec: return ServiceType::Vpn;
|
||||||
case DockerContainer::TorWebSite: return ServiceType::Other;
|
case DockerContainer::TorWebSite: return ServiceType::Other;
|
||||||
case DockerContainer::Dns: return ServiceType::Other;
|
case DockerContainer::Dns: return ServiceType::Other;
|
||||||
|
@ -160,6 +166,7 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
|
||||||
case DockerContainer::Cloak: return Proto::Cloak;
|
case DockerContainer::Cloak: return Proto::Cloak;
|
||||||
case DockerContainer::ShadowSocks: return Proto::ShadowSocks;
|
case DockerContainer::ShadowSocks: return Proto::ShadowSocks;
|
||||||
case DockerContainer::WireGuard: return Proto::WireGuard;
|
case DockerContainer::WireGuard: return Proto::WireGuard;
|
||||||
|
case DockerContainer::Awg: return Proto::Awg;
|
||||||
case DockerContainer::Ipsec: return Proto::Ikev2;
|
case DockerContainer::Ipsec: return Proto::Ikev2;
|
||||||
|
|
||||||
case DockerContainer::TorWebSite: return Proto::TorWebSite;
|
case DockerContainer::TorWebSite: return Proto::TorWebSite;
|
||||||
|
@ -179,6 +186,7 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case DockerContainer::WireGuard: return true;
|
case DockerContainer::WireGuard: return true;
|
||||||
case DockerContainer::OpenVpn: return true;
|
case DockerContainer::OpenVpn: return true;
|
||||||
|
case DockerContainer::Awg: return true;
|
||||||
case DockerContainer::Cloak:
|
case DockerContainer::Cloak:
|
||||||
return true;
|
return true;
|
||||||
// case DockerContainer::ShadowSocks: return true;
|
// case DockerContainer::ShadowSocks: return true;
|
||||||
|
@ -196,6 +204,7 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
|
||||||
case DockerContainer::WireGuard: return true;
|
case DockerContainer::WireGuard: return true;
|
||||||
case DockerContainer::OpenVpn: return true;
|
case DockerContainer::OpenVpn: return true;
|
||||||
case DockerContainer::ShadowSocks: return true;
|
case DockerContainer::ShadowSocks: return true;
|
||||||
|
case DockerContainer::Awg: return true;
|
||||||
case DockerContainer::Cloak: return true;
|
case DockerContainer::Cloak: return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
@ -224,8 +233,8 @@ bool ContainerProps::isEasySetupContainer(DockerContainer container)
|
||||||
{
|
{
|
||||||
switch (container) {
|
switch (container) {
|
||||||
case DockerContainer::WireGuard: return true;
|
case DockerContainer::WireGuard: return true;
|
||||||
|
case DockerContainer::Awg: return true;
|
||||||
case DockerContainer::Cloak: return true;
|
case DockerContainer::Cloak: return true;
|
||||||
case DockerContainer::OpenVpn: return true;
|
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,8 +243,8 @@ QString ContainerProps::easySetupHeader(DockerContainer container)
|
||||||
{
|
{
|
||||||
switch (container) {
|
switch (container) {
|
||||||
case DockerContainer::WireGuard: return tr("Low");
|
case DockerContainer::WireGuard: return tr("Low");
|
||||||
case DockerContainer::Cloak: return tr("High");
|
case DockerContainer::Awg: return tr("Medium or High");
|
||||||
case DockerContainer::OpenVpn: return tr("Medium");
|
case DockerContainer::Cloak: return tr("Extreme");
|
||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,9 +252,9 @@ QString ContainerProps::easySetupHeader(DockerContainer container)
|
||||||
QString ContainerProps::easySetupDescription(DockerContainer container)
|
QString ContainerProps::easySetupDescription(DockerContainer container)
|
||||||
{
|
{
|
||||||
switch (container) {
|
switch (container) {
|
||||||
case DockerContainer::WireGuard: return tr("I just want to increase the level of privacy");
|
case DockerContainer::WireGuard: return tr("I just want to increase the level of my privacy.");
|
||||||
case DockerContainer::Cloak: return tr("Many foreign websites and VPN providers are blocked");
|
case DockerContainer::Awg: return tr("I want to bypass censorship. This option recommended in most cases.");
|
||||||
case DockerContainer::OpenVpn: return tr("Some foreign sites are blocked, but VPN providers are not blocked");
|
case DockerContainer::Cloak: return tr("Most VPN protocols are blocked. Recommended if other options are not working.");
|
||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,9 +262,9 @@ QString ContainerProps::easySetupDescription(DockerContainer container)
|
||||||
int ContainerProps::easySetupOrder(DockerContainer container)
|
int ContainerProps::easySetupOrder(DockerContainer container)
|
||||||
{
|
{
|
||||||
switch (container) {
|
switch (container) {
|
||||||
case DockerContainer::WireGuard: return 1;
|
case DockerContainer::WireGuard: return 3;
|
||||||
case DockerContainer::Cloak: return 3;
|
case DockerContainer::Awg: return 2;
|
||||||
case DockerContainer::OpenVpn: return 2;
|
case DockerContainer::Cloak: return 1;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace amnezia
|
||||||
ShadowSocks,
|
ShadowSocks,
|
||||||
Cloak,
|
Cloak,
|
||||||
WireGuard,
|
WireGuard,
|
||||||
|
Awg,
|
||||||
Ipsec,
|
Ipsec,
|
||||||
|
|
||||||
// non-vpn
|
// non-vpn
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "scripts_registry.h"
|
#include "scripts_registry.h"
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
QString amnezia::scriptFolder(amnezia::DockerContainer container)
|
QString amnezia::scriptFolder(amnezia::DockerContainer container)
|
||||||
{
|
{
|
||||||
|
@ -11,11 +11,12 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container)
|
||||||
case DockerContainer::Cloak: return QLatin1String("openvpn_cloak");
|
case DockerContainer::Cloak: return QLatin1String("openvpn_cloak");
|
||||||
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
|
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
|
||||||
case DockerContainer::WireGuard: return QLatin1String("wireguard");
|
case DockerContainer::WireGuard: return QLatin1String("wireguard");
|
||||||
|
case DockerContainer::Awg: return QLatin1String("awg");
|
||||||
case DockerContainer::Ipsec: return QLatin1String("ipsec");
|
case DockerContainer::Ipsec: return QLatin1String("ipsec");
|
||||||
|
|
||||||
case DockerContainer::TorWebSite: return QLatin1String("website_tor");
|
case DockerContainer::TorWebSite: return QLatin1String("website_tor");
|
||||||
case DockerContainer::Dns: return QLatin1String("dns");
|
case DockerContainer::Dns: return QLatin1String("dns");
|
||||||
//case DockerContainer::FileShare: return QLatin1String("file_share");
|
// case DockerContainer::FileShare: return QLatin1String("file_share");
|
||||||
case DockerContainer::Sftp: return QLatin1String("sftp");
|
case DockerContainer::Sftp: return QLatin1String("sftp");
|
||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
|
@ -45,6 +46,7 @@ QString amnezia::scriptName(ProtocolScriptType type)
|
||||||
case ProtocolScriptType::container_startup: return QLatin1String("start.sh");
|
case ProtocolScriptType::container_startup: return QLatin1String("start.sh");
|
||||||
case ProtocolScriptType::openvpn_template: return QLatin1String("template.ovpn");
|
case ProtocolScriptType::openvpn_template: return QLatin1String("template.ovpn");
|
||||||
case ProtocolScriptType::wireguard_template: return QLatin1String("template.conf");
|
case ProtocolScriptType::wireguard_template: return QLatin1String("template.conf");
|
||||||
|
case ProtocolScriptType::awg_template: return QLatin1String("template.conf");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ QString amnezia::scriptData(amnezia::SharedScriptType type)
|
||||||
{
|
{
|
||||||
QString fileName = QString(":/server_scripts/%1").arg(amnezia::scriptName(type));
|
QString fileName = QString(":/server_scripts/%1").arg(amnezia::scriptName(type));
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (! file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
qDebug() << "Warning: script missing" << fileName;
|
qDebug() << "Warning: script missing" << fileName;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -67,7 +69,7 @@ QString amnezia::scriptData(amnezia::ProtocolScriptType type, DockerContainer co
|
||||||
{
|
{
|
||||||
QString fileName = QString(":/server_scripts/%1/%2").arg(amnezia::scriptFolder(container), amnezia::scriptName(type));
|
QString fileName = QString(":/server_scripts/%1/%2").arg(amnezia::scriptFolder(container), amnezia::scriptName(type));
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (! file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
qDebug() << "Warning: script missing" << fileName;
|
qDebug() << "Warning: script missing" << fileName;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@ enum ProtocolScriptType {
|
||||||
configure_container,
|
configure_container,
|
||||||
container_startup,
|
container_startup,
|
||||||
openvpn_template,
|
openvpn_template,
|
||||||
wireguard_template
|
wireguard_template,
|
||||||
|
awg_template
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -337,6 +337,10 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
||||||
!= newProtoConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort))
|
!= newProtoConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (container == DockerContainer::Awg) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -486,6 +490,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
||||||
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Proto::Cloak)).toObject();
|
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Proto::Cloak)).toObject();
|
||||||
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
|
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
|
||||||
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
|
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
|
||||||
|
const QJsonObject &amneziaWireguarConfig =
|
||||||
|
config.value(ProtocolProps::protoToString(Proto::Awg)).toObject();
|
||||||
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
|
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
|
||||||
|
|
||||||
Vars vars;
|
Vars vars;
|
||||||
|
@ -582,6 +588,37 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
||||||
vars.append({ { "$SFTP_USER", sftpConfig.value(config_key::userName).toString() } });
|
vars.append({ { "$SFTP_USER", sftpConfig.value(config_key::userName).toString() } });
|
||||||
vars.append({ { "$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() } });
|
vars.append({ { "$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() } });
|
||||||
|
|
||||||
|
// Amnezia wireguard vars
|
||||||
|
vars.append({ { "$AWG_SERVER_PORT",
|
||||||
|
amneziaWireguarConfig.value(config_key::port).toString(protocols::awg::defaultPort) } });
|
||||||
|
vars.append({ { "$JUNK_PACKET_COUNT",
|
||||||
|
amneziaWireguarConfig.value(config_key::junkPacketCount)
|
||||||
|
.toString(protocols::awg::defaultJunkPacketCount) } });
|
||||||
|
vars.append({ { "$JUNK_PACKET_MIN_SIZE",
|
||||||
|
amneziaWireguarConfig.value(config_key::junkPacketMinSize)
|
||||||
|
.toString(protocols::awg::defaultJunkPacketMinSize) } });
|
||||||
|
vars.append({ { "$JUNK_PACKET_MAX_SIZE",
|
||||||
|
amneziaWireguarConfig.value(config_key::junkPacketMaxSize)
|
||||||
|
.toString(protocols::awg::defaultJunkPacketMaxSize) } });
|
||||||
|
vars.append({ { "$INIT_PACKET_JUNK_SIZE",
|
||||||
|
amneziaWireguarConfig.value(config_key::initPacketJunkSize)
|
||||||
|
.toString(protocols::awg::defaultInitPacketJunkSize) } });
|
||||||
|
vars.append({ { "$RESPONSE_PACKET_JUNK_SIZE",
|
||||||
|
amneziaWireguarConfig.value(config_key::responsePacketJunkSize)
|
||||||
|
.toString(protocols::awg::defaultResponsePacketJunkSize) } });
|
||||||
|
vars.append({ { "$INIT_PACKET_MAGIC_HEADER",
|
||||||
|
amneziaWireguarConfig.value(config_key::initPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultInitPacketMagicHeader) } });
|
||||||
|
vars.append({ { "$RESPONSE_PACKET_MAGIC_HEADER",
|
||||||
|
amneziaWireguarConfig.value(config_key::responsePacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultResponsePacketMagicHeader) } });
|
||||||
|
vars.append({ { "$UNDERLOAD_PACKET_MAGIC_HEADER",
|
||||||
|
amneziaWireguarConfig.value(config_key::underloadPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultUnderloadPacketMagicHeader) } });
|
||||||
|
vars.append({ { "$TRANSPORT_PACKET_MAGIC_HEADER",
|
||||||
|
amneziaWireguarConfig.value(config_key::transportPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultTransportPacketMagicHeader) } });
|
||||||
|
|
||||||
QString serverIp = Utils::getIPAddress(credentials.hostName);
|
QString serverIp = Utils::getIPAddress(credentials.hostName);
|
||||||
if (!serverIp.isEmpty()) {
|
if (!serverIp.isEmpty()) {
|
||||||
vars.append({ { "$SERVER_IP_ADDRESS", serverIp } });
|
vars.append({ { "$SERVER_IP_ADDRESS", serverIp } });
|
||||||
|
|
|
@ -359,6 +359,23 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
||||||
if (!parseStringList(obj, "vpnDisabledApps", config.m_vpnDisabledApps)) {
|
if (!parseStringList(obj, "vpnDisabledApps", config.m_vpnDisabledApps)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!obj.value("Jc").isNull() && !obj.value("Jmin").isNull()
|
||||||
|
&& !obj.value("Jmax").isNull() && !obj.value("S1").isNull()
|
||||||
|
&& !obj.value("S2").isNull() && !obj.value("H1").isNull()
|
||||||
|
&& !obj.value("H2").isNull() && !obj.value("H3").isNull()
|
||||||
|
&& !obj.value("H4").isNull()) {
|
||||||
|
config.m_junkPacketCount = obj.value("Jc").toString();
|
||||||
|
config.m_junkPacketMinSize = obj.value("Jmin").toString();
|
||||||
|
config.m_junkPacketMaxSize = obj.value("Jmax").toString();
|
||||||
|
config.m_initPacketJunkSize = obj.value("S1").toString();
|
||||||
|
config.m_responsePacketJunkSize = obj.value("S2").toString();
|
||||||
|
config.m_initPacketMagicHeader = obj.value("H1").toString();
|
||||||
|
config.m_responsePacketMagicHeader = obj.value("H2").toString();
|
||||||
|
config.m_underloadPacketMagicHeader = obj.value("H3").toString();
|
||||||
|
config.m_transportPacketMagicHeader = obj.value("H4").toString();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,34 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
|
||||||
out << "DNS = " << dnsServers.join(", ") << "\n";
|
out << "DNS = " << dnsServers.join(", ") << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_junkPacketCount.isNull()) {
|
||||||
|
out << "Jc = " << m_junkPacketCount << "\n";
|
||||||
|
}
|
||||||
|
if (!m_junkPacketMinSize.isNull()) {
|
||||||
|
out << "JMin = " << m_junkPacketMinSize << "\n";
|
||||||
|
}
|
||||||
|
if (!m_junkPacketMaxSize.isNull()) {
|
||||||
|
out << "JMax = " << m_junkPacketMaxSize << "\n";
|
||||||
|
}
|
||||||
|
if (!m_initPacketJunkSize.isNull()) {
|
||||||
|
out << "S1 = " << m_initPacketJunkSize << "\n";
|
||||||
|
}
|
||||||
|
if (!m_responsePacketJunkSize.isNull()) {
|
||||||
|
out << "S2 = " << m_responsePacketJunkSize << "\n";
|
||||||
|
}
|
||||||
|
if (!m_initPacketMagicHeader.isNull()) {
|
||||||
|
out << "H1 = " << m_initPacketMagicHeader << "\n";
|
||||||
|
}
|
||||||
|
if (!m_responsePacketMagicHeader.isNull()) {
|
||||||
|
out << "H2 = " << m_responsePacketMagicHeader << "\n";
|
||||||
|
}
|
||||||
|
if (!m_underloadPacketMagicHeader.isNull()) {
|
||||||
|
out << "H3 = " << m_underloadPacketMagicHeader << "\n";
|
||||||
|
}
|
||||||
|
if (!m_transportPacketMagicHeader.isNull()) {
|
||||||
|
out << "H4 = " << m_transportPacketMagicHeader << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// If any extra config was provided, append it now.
|
// If any extra config was provided, append it now.
|
||||||
for (const QString& key : extra.keys()) {
|
for (const QString& key : extra.keys()) {
|
||||||
out << key << " = " << extra[key] << "\n";
|
out << key << " = " << extra[key] << "\n";
|
||||||
|
|
|
@ -40,6 +40,16 @@ class InterfaceConfig {
|
||||||
QString m_installationId;
|
QString m_installationId;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QString m_junkPacketCount;
|
||||||
|
QString m_junkPacketMinSize;
|
||||||
|
QString m_junkPacketMaxSize;
|
||||||
|
QString m_initPacketJunkSize;
|
||||||
|
QString m_responsePacketJunkSize;
|
||||||
|
QString m_initPacketMagicHeader;
|
||||||
|
QString m_responsePacketMagicHeader;
|
||||||
|
QString m_underloadPacketMagicHeader;
|
||||||
|
QString m_transportPacketMagicHeader;
|
||||||
|
|
||||||
QJsonObject toJson() const;
|
QJsonObject toJson() const;
|
||||||
QString toWgConf(
|
QString toWgConf(
|
||||||
const QMap<QString, QString>& extra = QMap<QString, QString>()) const;
|
const QMap<QString, QString>& extra = QMap<QString, QString>()) const;
|
||||||
|
|
|
@ -58,7 +58,7 @@ target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
|
||||||
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||||
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
||||||
|
|
||||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources)
|
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/awg-apple/Sources)
|
||||||
|
|
||||||
target_sources(networkextension PRIVATE
|
target_sources(networkextension PRIVATE
|
||||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "wireguard-go-version.h"
|
#include "wireguard-go-version.h"
|
||||||
#include "3rd/wireguard-apple/Sources/WireGuardKitGo/wireguard.h"
|
#include "3rd/awg-apple/Sources/WireGuardKitGo/wireguard.h"
|
||||||
#include "3rd/wireguard-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
#include "3rd/awg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "wireguard-go-version.h"
|
#include "wireguard-go-version.h"
|
||||||
#include "3rd/wireguard-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
#include "3rd/awg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "macos/gobridge/wireguard.h"
|
#include "macos/gobridge/wireguard.h"
|
||||||
#include "wireguard-go-version.h"
|
#include "wireguard-go-version.h"
|
||||||
#include "3rd/wireguard-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
#include "3rd/awg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||||
#include "3rd/ShadowSocks/ShadowSocks/ShadowSocks.h"
|
#include "3rd/ShadowSocks/ShadowSocks/ShadowSocks.h"
|
||||||
#include "platforms/ios/ssconnectivity.h"
|
#include "platforms/ios/ssconnectivity.h"
|
||||||
#include "platforms/ios/iosopenvpn2ssadapter.h"
|
#include "platforms/ios/iosopenvpn2ssadapter.h"
|
||||||
|
|
|
@ -115,7 +115,9 @@ void LocalSocketController::daemonConnected() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
QJsonObject wgConfig = rawConfig.value("wireguard_config_data").toObject();
|
QString protocolName = rawConfig.value("protocol").toString();
|
||||||
|
|
||||||
|
QJsonObject wgConfig = rawConfig.value(protocolName + "_config_data").toObject();
|
||||||
|
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
json.insert("type", "activate");
|
json.insert("type", "activate");
|
||||||
|
@ -160,6 +162,19 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
// splitTunnelApps.append(QJsonValue(uri));
|
// splitTunnelApps.append(QJsonValue(uri));
|
||||||
// }
|
// }
|
||||||
// json.insert("vpnDisabledApps", splitTunnelApps);
|
// json.insert("vpnDisabledApps", splitTunnelApps);
|
||||||
|
|
||||||
|
if (protocolName == amnezia::config_key::awg) {
|
||||||
|
json.insert(amnezia::config_key::junkPacketCount, wgConfig.value(amnezia::config_key::junkPacketCount));
|
||||||
|
json.insert(amnezia::config_key::junkPacketMinSize, wgConfig.value(amnezia::config_key::junkPacketMinSize));
|
||||||
|
json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize));
|
||||||
|
json.insert(amnezia::config_key::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize));
|
||||||
|
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
|
||||||
|
json.insert(amnezia::config_key::initPacketMagicHeader, wgConfig.value(amnezia::config_key::initPacketMagicHeader));
|
||||||
|
json.insert(amnezia::config_key::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader));
|
||||||
|
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
||||||
|
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
||||||
|
}
|
||||||
|
|
||||||
write(json);
|
write(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "3rd/wireguard-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
#include "3rd/awg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
@ -62,6 +62,7 @@ private:
|
||||||
bool setupOpenVPN();
|
bool setupOpenVPN();
|
||||||
bool setupCloak();
|
bool setupCloak();
|
||||||
bool setupWireGuard();
|
bool setupWireGuard();
|
||||||
|
bool setupAwg();
|
||||||
|
|
||||||
bool startOpenVPN(const QString &config);
|
bool startOpenVPN(const QString &config);
|
||||||
bool startWireGuard(const QString &jsonConfig);
|
bool startWireGuard(const QString &jsonConfig);
|
||||||
|
|
|
@ -204,6 +204,9 @@ bool IosController::connectVpn(amnezia::Proto proto, const QJsonObject& configur
|
||||||
if (proto == amnezia::Proto::WireGuard) {
|
if (proto == amnezia::Proto::WireGuard) {
|
||||||
return setupWireGuard();
|
return setupWireGuard();
|
||||||
}
|
}
|
||||||
|
if (proto == amnezia::Proto::Awg) {
|
||||||
|
return setupAwg();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -307,6 +310,15 @@ bool IosController::setupWireGuard()
|
||||||
return startWireGuard(wgConfig);
|
return startWireGuard(wgConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IosController::setupAwg()
|
||||||
|
{
|
||||||
|
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::Awg)].toObject();
|
||||||
|
|
||||||
|
QString wgConfig = config[config_key::config].toString();
|
||||||
|
|
||||||
|
return startWireGuard(wgConfig);
|
||||||
|
}
|
||||||
|
|
||||||
bool IosController::startOpenVPN(const QString &config)
|
bool IosController::startOpenVPN(const QString &config)
|
||||||
{
|
{
|
||||||
qDebug() << "IosController::startOpenVPN";
|
qDebug() << "IosController::startOpenVPN";
|
||||||
|
|
|
@ -100,6 +100,19 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||||
QTextStream out(&message);
|
QTextStream out(&message);
|
||||||
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
||||||
out << "replace_peers=true\n";
|
out << "replace_peers=true\n";
|
||||||
|
|
||||||
|
if (config.m_junkPacketCount != "") {
|
||||||
|
out << "jc=" << config.m_junkPacketCount << "\n";
|
||||||
|
out << "jmin=" << config.m_junkPacketMinSize << "\n";
|
||||||
|
out << "jmax=" << config.m_junkPacketMaxSize << "\n";
|
||||||
|
out << "s1=" << config.m_initPacketJunkSize << "\n";
|
||||||
|
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
||||||
|
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
||||||
|
out << "h2=" << config.m_responsePacketMagicHeader << "\n";
|
||||||
|
out << "h3=" << config.m_underloadPacketMagicHeader << "\n";
|
||||||
|
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
int err = uapiErrno(uapiCommand(message));
|
int err = uapiErrno(uapiCommand(message));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
logger.error() << "Interface configuration failed:" << strerror(err);
|
logger.error() << "Interface configuration failed:" << strerror(err);
|
||||||
|
|
|
@ -100,6 +100,19 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||||
QTextStream out(&message);
|
QTextStream out(&message);
|
||||||
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
out << "private_key=" << QString(privateKey.toHex()) << "\n";
|
||||||
out << "replace_peers=true\n";
|
out << "replace_peers=true\n";
|
||||||
|
|
||||||
|
if (config.m_junkPacketCount != "") {
|
||||||
|
out << "jc=" << config.m_junkPacketCount << "\n";
|
||||||
|
out << "jmin=" << config.m_junkPacketMinSize << "\n";
|
||||||
|
out << "jmax=" << config.m_junkPacketMaxSize << "\n";
|
||||||
|
out << "s1=" << config.m_initPacketJunkSize << "\n";
|
||||||
|
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
||||||
|
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
||||||
|
out << "h2=" << config.m_responsePacketMagicHeader << "\n";
|
||||||
|
out << "h3=" << config.m_underloadPacketMagicHeader << "\n";
|
||||||
|
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
int err = uapiErrno(uapiCommand(message));
|
int err = uapiErrno(uapiCommand(message));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
logger.error() << "Interface configuration failed:" << strerror(err);
|
logger.error() << "Interface configuration failed:" << strerror(err);
|
||||||
|
|
10
client/protocols/awgprotocol.cpp
Normal file
10
client/protocols/awgprotocol.cpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "awgprotocol.h"
|
||||||
|
|
||||||
|
Awg::Awg(const QJsonObject &configuration, QObject *parent)
|
||||||
|
: WireguardProtocol(configuration, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Awg::~Awg()
|
||||||
|
{
|
||||||
|
}
|
17
client/protocols/awgprotocol.h
Normal file
17
client/protocols/awgprotocol.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef AWGPROTOCOL_H
|
||||||
|
#define AWGPROTOCOL_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "wireguardprotocol.h"
|
||||||
|
|
||||||
|
class Awg : public WireguardProtocol
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Awg(const QJsonObject &configuration, QObject *parent = nullptr);
|
||||||
|
virtual ~Awg() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AWGPROTOCOL_H
|
|
@ -66,6 +66,7 @@ QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
||||||
{ Proto::ShadowSocks, "ShadowSocks" },
|
{ Proto::ShadowSocks, "ShadowSocks" },
|
||||||
{ Proto::Cloak, "Cloak" },
|
{ Proto::Cloak, "Cloak" },
|
||||||
{ Proto::WireGuard, "WireGuard" },
|
{ Proto::WireGuard, "WireGuard" },
|
||||||
|
{ Proto::WireGuard, "AmneziaWG" },
|
||||||
{ Proto::Ikev2, "IKEv2" },
|
{ Proto::Ikev2, "IKEv2" },
|
||||||
{ Proto::L2tp, "L2TP" },
|
{ Proto::L2tp, "L2TP" },
|
||||||
|
|
||||||
|
@ -88,6 +89,7 @@ amnezia::ServiceType ProtocolProps::protocolService(Proto p)
|
||||||
case Proto::Cloak: return ServiceType::Vpn;
|
case Proto::Cloak: return ServiceType::Vpn;
|
||||||
case Proto::ShadowSocks: return ServiceType::Vpn;
|
case Proto::ShadowSocks: return ServiceType::Vpn;
|
||||||
case Proto::WireGuard: return ServiceType::Vpn;
|
case Proto::WireGuard: return ServiceType::Vpn;
|
||||||
|
case Proto::Awg: return ServiceType::Vpn;
|
||||||
case Proto::TorWebSite: return ServiceType::Other;
|
case Proto::TorWebSite: return ServiceType::Other;
|
||||||
case Proto::Dns: return ServiceType::Other;
|
case Proto::Dns: return ServiceType::Other;
|
||||||
case Proto::FileShare: return ServiceType::Other;
|
case Proto::FileShare: return ServiceType::Other;
|
||||||
|
@ -103,6 +105,7 @@ int ProtocolProps::defaultPort(Proto p)
|
||||||
case Proto::Cloak: return 443;
|
case Proto::Cloak: return 443;
|
||||||
case Proto::ShadowSocks: return 6789;
|
case Proto::ShadowSocks: return 6789;
|
||||||
case Proto::WireGuard: return 51820;
|
case Proto::WireGuard: return 51820;
|
||||||
|
case Proto::Awg: return 55424;
|
||||||
case Proto::Ikev2: return -1;
|
case Proto::Ikev2: return -1;
|
||||||
case Proto::L2tp: return -1;
|
case Proto::L2tp: return -1;
|
||||||
|
|
||||||
|
@ -122,6 +125,7 @@ bool ProtocolProps::defaultPortChangeable(Proto p)
|
||||||
case Proto::Cloak: return true;
|
case Proto::Cloak: return true;
|
||||||
case Proto::ShadowSocks: return true;
|
case Proto::ShadowSocks: return true;
|
||||||
case Proto::WireGuard: return true;
|
case Proto::WireGuard: return true;
|
||||||
|
case Proto::Awg: return true;
|
||||||
case Proto::Ikev2: return false;
|
case Proto::Ikev2: return false;
|
||||||
case Proto::L2tp: return false;
|
case Proto::L2tp: return false;
|
||||||
|
|
||||||
|
@ -140,6 +144,7 @@ TransportProto ProtocolProps::defaultTransportProto(Proto p)
|
||||||
case Proto::Cloak: return TransportProto::Tcp;
|
case Proto::Cloak: return TransportProto::Tcp;
|
||||||
case Proto::ShadowSocks: return TransportProto::Tcp;
|
case Proto::ShadowSocks: return TransportProto::Tcp;
|
||||||
case Proto::WireGuard: return TransportProto::Udp;
|
case Proto::WireGuard: return TransportProto::Udp;
|
||||||
|
case Proto::Awg: return TransportProto::Udp;
|
||||||
case Proto::Ikev2: return TransportProto::Udp;
|
case Proto::Ikev2: return TransportProto::Udp;
|
||||||
case Proto::L2tp: return TransportProto::Udp;
|
case Proto::L2tp: return TransportProto::Udp;
|
||||||
// non-vpn
|
// non-vpn
|
||||||
|
@ -158,6 +163,7 @@ bool ProtocolProps::defaultTransportProtoChangeable(Proto p)
|
||||||
case Proto::Cloak: return false;
|
case Proto::Cloak: return false;
|
||||||
case Proto::ShadowSocks: return false;
|
case Proto::ShadowSocks: return false;
|
||||||
case Proto::WireGuard: return false;
|
case Proto::WireGuard: return false;
|
||||||
|
case Proto::Awg: return false;
|
||||||
case Proto::Ikev2: return false;
|
case Proto::Ikev2: return false;
|
||||||
case Proto::L2tp: return false;
|
case Proto::L2tp: return false;
|
||||||
// non-vpn
|
// non-vpn
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#define PROTOCOLS_DEFS_H
|
#define PROTOCOLS_DEFS_H
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
|
||||||
#include <QMetaEnum>
|
#include <QMetaEnum>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
namespace amnezia
|
namespace amnezia
|
||||||
{
|
{
|
||||||
|
@ -61,11 +61,22 @@ namespace amnezia
|
||||||
|
|
||||||
constexpr char isThirdPartyConfig[] = "isThirdPartyConfig";
|
constexpr char isThirdPartyConfig[] = "isThirdPartyConfig";
|
||||||
|
|
||||||
|
constexpr char junkPacketCount[] = "Jc";
|
||||||
|
constexpr char junkPacketMinSize[] = "Jmin";
|
||||||
|
constexpr char junkPacketMaxSize[] = "Jmax";
|
||||||
|
constexpr char initPacketJunkSize[] = "S1";
|
||||||
|
constexpr char responsePacketJunkSize[] = "S2";
|
||||||
|
constexpr char initPacketMagicHeader[] = "H1";
|
||||||
|
constexpr char responsePacketMagicHeader[] = "H2";
|
||||||
|
constexpr char underloadPacketMagicHeader[] = "H3";
|
||||||
|
constexpr char transportPacketMagicHeader[] = "H4";
|
||||||
|
|
||||||
constexpr char openvpn[] = "openvpn";
|
constexpr char openvpn[] = "openvpn";
|
||||||
constexpr char wireguard[] = "wireguard";
|
constexpr char wireguard[] = "wireguard";
|
||||||
constexpr char shadowsocks[] = "shadowsocks";
|
constexpr char shadowsocks[] = "shadowsocks";
|
||||||
constexpr char cloak[] = "cloak";
|
constexpr char cloak[] = "cloak";
|
||||||
constexpr char sftp[] = "sftp";
|
constexpr char sftp[] = "sftp";
|
||||||
|
constexpr char awg[] = "awg";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +151,25 @@ namespace amnezia
|
||||||
|
|
||||||
} // namespace sftp
|
} // namespace sftp
|
||||||
|
|
||||||
|
namespace awg
|
||||||
|
{
|
||||||
|
constexpr char defaultPort[] = "55424";
|
||||||
|
|
||||||
|
constexpr char serverConfigPath[] = "/opt/amnezia/awg/wg0.conf";
|
||||||
|
constexpr char serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key";
|
||||||
|
constexpr char serverPskKeyPath[] = "/opt/amnezia/awg/wireguard_psk.key";
|
||||||
|
|
||||||
|
constexpr char defaultJunkPacketCount[] = "3";
|
||||||
|
constexpr char defaultJunkPacketMinSize[] = "10";
|
||||||
|
constexpr char defaultJunkPacketMaxSize[] = "30";
|
||||||
|
constexpr char defaultInitPacketJunkSize[] = "15";
|
||||||
|
constexpr char defaultResponsePacketJunkSize[] = "18";
|
||||||
|
constexpr char defaultInitPacketMagicHeader[] = "1020325451";
|
||||||
|
constexpr char defaultResponsePacketMagicHeader[] = "3288052141";
|
||||||
|
constexpr char defaultTransportPacketMagicHeader[] = "2528465083";
|
||||||
|
constexpr char defaultUnderloadPacketMagicHeader[] = "1766607858";
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace protocols
|
} // namespace protocols
|
||||||
|
|
||||||
namespace ProtocolEnumNS
|
namespace ProtocolEnumNS
|
||||||
|
@ -158,6 +188,7 @@ namespace amnezia
|
||||||
ShadowSocks,
|
ShadowSocks,
|
||||||
Cloak,
|
Cloak,
|
||||||
WireGuard,
|
WireGuard,
|
||||||
|
Awg,
|
||||||
Ikev2,
|
Ikev2,
|
||||||
L2tp,
|
L2tp,
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "vpnprotocol.h"
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
#include "vpnprotocol.h"
|
||||||
|
|
||||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
|
||||||
#include "openvpnprotocol.h"
|
#include "openvpnovercloakprotocol.h"
|
||||||
#include "shadowsocksvpnprotocol.h"
|
#include "openvpnprotocol.h"
|
||||||
#include "openvpnovercloakprotocol.h"
|
#include "shadowsocksvpnprotocol.h"
|
||||||
#include "wireguardprotocol.h"
|
#include "wireguardprotocol.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
#include "ikev2_vpn_protocol_windows.h"
|
#include "ikev2_vpn_protocol_windows.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent)
|
||||||
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent)
|
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_connectionState(Vpn::ConnectionState::Unknown),
|
m_connectionState(Vpn::ConnectionState::Unknown),
|
||||||
m_rawConfig(configuration),
|
m_rawConfig(configuration),
|
||||||
|
@ -31,7 +30,7 @@ VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent)
|
||||||
void VpnProtocol::setLastError(ErrorCode lastError)
|
void VpnProtocol::setLastError(ErrorCode lastError)
|
||||||
{
|
{
|
||||||
m_lastError = lastError;
|
m_lastError = lastError;
|
||||||
if (lastError){
|
if (lastError) {
|
||||||
setConnectionState(Vpn::ConnectionState::Error);
|
setConnectionState(Vpn::ConnectionState::Error);
|
||||||
}
|
}
|
||||||
qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError);
|
qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError);
|
||||||
|
@ -103,7 +102,7 @@ QString VpnProtocol::vpnGateway() const
|
||||||
return m_vpnGateway;
|
return m_vpnGateway;
|
||||||
}
|
}
|
||||||
|
|
||||||
VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject& configuration)
|
VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &configuration)
|
||||||
{
|
{
|
||||||
switch (container) {
|
switch (container) {
|
||||||
#if defined(Q_OS_WINDOWS)
|
#if defined(Q_OS_WINDOWS)
|
||||||
|
@ -114,6 +113,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject&
|
||||||
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
|
||||||
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);
|
||||||
case DockerContainer::WireGuard: return new WireguardProtocol(configuration);
|
case DockerContainer::WireGuard: return new WireguardProtocol(configuration);
|
||||||
|
case DockerContainer::Awg: return new WireguardProtocol(configuration);
|
||||||
#endif
|
#endif
|
||||||
default: return nullptr;
|
default: return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -135,8 +135,7 @@ QString VpnProtocol::textConnectionState(Vpn::ConnectionState connectionState)
|
||||||
case Vpn::ConnectionState::Disconnecting: return tr("Disconnecting...");
|
case Vpn::ConnectionState::Disconnecting: return tr("Disconnecting...");
|
||||||
case Vpn::ConnectionState::Reconnecting: return tr("Reconnecting...");
|
case Vpn::ConnectionState::Reconnecting: return tr("Reconnecting...");
|
||||||
case Vpn::ConnectionState::Error: return tr("Error");
|
case Vpn::ConnectionState::Error: return tr("Error");
|
||||||
default:
|
default:;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QString();
|
return QString();
|
||||||
|
|
|
@ -216,5 +216,11 @@
|
||||||
<file>ui/qml/Pages2/PageServiceDnsSettings.qml</file>
|
<file>ui/qml/Pages2/PageServiceDnsSettings.qml</file>
|
||||||
<file>ui/qml/Controls2/TopCloseButtonType.qml</file>
|
<file>ui/qml/Controls2/TopCloseButtonType.qml</file>
|
||||||
<file>images/controls/x-circle.svg</file>
|
<file>images/controls/x-circle.svg</file>
|
||||||
|
<file>ui/qml/Pages2/PageProtocolAwgSettings.qml</file>
|
||||||
|
<file>server_scripts/awg/template.conf</file>
|
||||||
|
<file>server_scripts/awg/start.sh</file>
|
||||||
|
<file>server_scripts/awg/configure_container.sh</file>
|
||||||
|
<file>server_scripts/awg/run_container.sh</file>
|
||||||
|
<file>server_scripts/awg/Dockerfile</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
46
client/server_scripts/awg/Dockerfile
Normal file
46
client/server_scripts/awg/Dockerfile
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
FROM amneziavpn/amnezia-wg:latest
|
||||||
|
|
||||||
|
LABEL maintainer="AmneziaVPN"
|
||||||
|
|
||||||
|
#Install required packages
|
||||||
|
RUN apk add --no-cache bash curl dumb-init
|
||||||
|
RUN apk --update upgrade --no-cache
|
||||||
|
|
||||||
|
RUN mkdir -p /opt/amnezia
|
||||||
|
RUN echo -e "#!/bin/bash\ntail -f /dev/null" > /opt/amnezia/start.sh
|
||||||
|
RUN chmod a+x /opt/amnezia/start.sh
|
||||||
|
|
||||||
|
# Tune network
|
||||||
|
RUN echo -e " \n\
|
||||||
|
fs.file-max = 51200 \n\
|
||||||
|
\n\
|
||||||
|
net.core.rmem_max = 67108864 \n\
|
||||||
|
net.core.wmem_max = 67108864 \n\
|
||||||
|
net.core.netdev_max_backlog = 250000 \n\
|
||||||
|
net.core.somaxconn = 4096 \n\
|
||||||
|
\n\
|
||||||
|
net.ipv4.tcp_syncookies = 1 \n\
|
||||||
|
net.ipv4.tcp_tw_reuse = 1 \n\
|
||||||
|
net.ipv4.tcp_tw_recycle = 0 \n\
|
||||||
|
net.ipv4.tcp_fin_timeout = 30 \n\
|
||||||
|
net.ipv4.tcp_keepalive_time = 1200 \n\
|
||||||
|
net.ipv4.ip_local_port_range = 10000 65000 \n\
|
||||||
|
net.ipv4.tcp_max_syn_backlog = 8192 \n\
|
||||||
|
net.ipv4.tcp_max_tw_buckets = 5000 \n\
|
||||||
|
net.ipv4.tcp_fastopen = 3 \n\
|
||||||
|
net.ipv4.tcp_mem = 25600 51200 102400 \n\
|
||||||
|
net.ipv4.tcp_rmem = 4096 87380 67108864 \n\
|
||||||
|
net.ipv4.tcp_wmem = 4096 65536 67108864 \n\
|
||||||
|
net.ipv4.tcp_mtu_probing = 1 \n\
|
||||||
|
net.ipv4.tcp_congestion_control = hybla \n\
|
||||||
|
# for low-latency network, use cubic instead \n\
|
||||||
|
# net.ipv4.tcp_congestion_control = cubic \n\
|
||||||
|
" | sed -e 's/^\s\+//g' | tee -a /etc/sysctl.conf && \
|
||||||
|
mkdir -p /etc/security && \
|
||||||
|
echo -e " \n\
|
||||||
|
* soft nofile 51200 \n\
|
||||||
|
* hard nofile 51200 \n\
|
||||||
|
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
|
||||||
|
|
||||||
|
ENTRYPOINT [ "dumb-init", "/opt/amnezia/start.sh" ]
|
||||||
|
CMD [ "" ]
|
26
client/server_scripts/awg/configure_container.sh
Normal file
26
client/server_scripts/awg/configure_container.sh
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
mkdir -p /opt/amnezia/awg
|
||||||
|
cd /opt/amnezia/awg
|
||||||
|
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey)
|
||||||
|
echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/awg/wireguard_server_private_key.key
|
||||||
|
|
||||||
|
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey)
|
||||||
|
echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/awg/wireguard_server_public_key.key
|
||||||
|
|
||||||
|
WIREGUARD_PSK=$(wg genpsk)
|
||||||
|
echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key
|
||||||
|
|
||||||
|
cat > /opt/amnezia/awg/wg0.conf <<EOF
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY
|
||||||
|
Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR
|
||||||
|
ListenPort = $AWG_SERVER_PORT
|
||||||
|
Jc = $JUNK_PACKET_COUNT
|
||||||
|
Jmin = $JUNK_PACKET_MIN_SIZE
|
||||||
|
Jmax = $JUNK_PACKET_MAX_SIZE
|
||||||
|
S1 = $INIT_PACKET_JUNK_SIZE
|
||||||
|
S2 = $RESPONSE_PACKET_JUNK_SIZE
|
||||||
|
H1 = $INIT_PACKET_MAGIC_HEADER
|
||||||
|
H2 = $RESPONSE_PACKET_MAGIC_HEADER
|
||||||
|
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
|
||||||
|
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
|
||||||
|
EOF
|
18
client/server_scripts/awg/run_container.sh
Normal file
18
client/server_scripts/awg/run_container.sh
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Run container
|
||||||
|
sudo docker run -d \
|
||||||
|
--log-driver none \
|
||||||
|
--restart always \
|
||||||
|
--privileged \
|
||||||
|
--cap-add=NET_ADMIN \
|
||||||
|
--cap-add=SYS_MODULE \
|
||||||
|
-p $AWG_SERVER_PORT:$AWG_SERVER_PORT/udp \
|
||||||
|
-v /lib/modules:/lib/modules \
|
||||||
|
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
|
||||||
|
--name $CONTAINER_NAME \
|
||||||
|
$CONTAINER_NAME
|
||||||
|
|
||||||
|
sudo docker network connect amnezia-dns-net $CONTAINER_NAME
|
||||||
|
|
||||||
|
# Prevent to route packets outside of the container in case if server behind of the NAT
|
||||||
|
#sudo docker exec -i $CONTAINER_NAME sh -c "ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up"
|
||||||
|
|
28
client/server_scripts/awg/start.sh
Normal file
28
client/server_scripts/awg/start.sh
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This scripts copied from Amnezia client to Docker container to /opt/amnezia and launched every time container starts
|
||||||
|
|
||||||
|
echo "Container startup"
|
||||||
|
#ifconfig eth0:0 $SERVER_IP_ADDRESS netmask 255.255.255.255 up
|
||||||
|
|
||||||
|
# kill daemons in case of restart
|
||||||
|
wg-quick down /opt/amnezia/awg/wg0.conf
|
||||||
|
|
||||||
|
# start daemons if configured
|
||||||
|
if [ -f /opt/amnezia/awg/wg0.conf ]; then (wg-quick up /opt/amnezia/awg/wg0.conf); fi
|
||||||
|
|
||||||
|
# Allow traffic on the TUN interface.
|
||||||
|
iptables -A INPUT -i wg0 -j ACCEPT
|
||||||
|
iptables -A FORWARD -i wg0 -j ACCEPT
|
||||||
|
iptables -A OUTPUT -o wg0 -j ACCEPT
|
||||||
|
|
||||||
|
# Allow forwarding traffic only from the VPN.
|
||||||
|
iptables -A FORWARD -i wg0 -o eth0 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
|
||||||
|
iptables -A FORWARD -i wg0 -o eth1 -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -j ACCEPT
|
||||||
|
|
||||||
|
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
|
|
||||||
|
iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth0 -j MASQUERADE
|
||||||
|
iptables -t nat -A POSTROUTING -s $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR -o eth1 -j MASQUERADE
|
||||||
|
|
||||||
|
tail -f /dev/null
|
20
client/server_scripts/awg/template.conf
Normal file
20
client/server_scripts/awg/template.conf
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[Interface]
|
||||||
|
Address = $WIREGUARD_CLIENT_IP/32
|
||||||
|
DNS = $PRIMARY_DNS, $SECONDARY_DNS
|
||||||
|
PrivateKey = $WIREGUARD_CLIENT_PRIVATE_KEY
|
||||||
|
Jc = $JUNK_PACKET_COUNT
|
||||||
|
Jmin = $JUNK_PACKET_MIN_SIZE
|
||||||
|
Jmax = $JUNK_PACKET_MAX_SIZE
|
||||||
|
S1 = $INIT_PACKET_JUNK_SIZE
|
||||||
|
S2 = $RESPONSE_PACKET_JUNK_SIZE
|
||||||
|
H1 = $INIT_PACKET_MAGIC_HEADER
|
||||||
|
H2 = $RESPONSE_PACKET_MAGIC_HEADER
|
||||||
|
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
|
||||||
|
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $WIREGUARD_SERVER_PUBLIC_KEY
|
||||||
|
PresharedKey = $WIREGUARD_PSK
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
Endpoint = $SERVER_IP_ADDRESS:$AWG_SERVER_PORT
|
||||||
|
PersistentKeepalive = 25
|
|
@ -1 +1 @@
|
||||||
sudo docker build -t $CONTAINER_NAME $DOCKERFILE_FOLDER --build-arg SERVER_ARCH=$(uname -m)
|
sudo docker build --no-cache --pull -t $CONTAINER_NAME $DOCKERFILE_FOLDER --build-arg SERVER_ARCH=$(uname -m)
|
||||||
|
|
|
@ -122,7 +122,7 @@
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Components/HomeContainersListView.qml" line="77"/>
|
<location filename="../ui/qml/Components/HomeContainersListView.qml" line="76"/>
|
||||||
<source>Reconnect via VPN Procotol: </source>
|
<source>Reconnect via VPN Procotol: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -265,6 +265,94 @@ Already installed containers were found on the server. All installed containers
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>PageProtocolAwgSettings</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="76"/>
|
||||||
|
<source>AmneziaWG settings</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="84"/>
|
||||||
|
<source>Port</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="103"/>
|
||||||
|
<source>Junk packet count</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="126"/>
|
||||||
|
<source>Junk packet minimum size</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="144"/>
|
||||||
|
<source>Junk packet maximum size</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="162"/>
|
||||||
|
<source>Init packet junk size</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="180"/>
|
||||||
|
<source>Response packet junk size</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="198"/>
|
||||||
|
<source>Init packet magic header</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="216"/>
|
||||||
|
<source>Response packet magic header</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="234"/>
|
||||||
|
<source>Transport packet magic header</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="252"/>
|
||||||
|
<source>Underload packet magic header</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="275"/>
|
||||||
|
<source>Remove AmneziaWG</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="278"/>
|
||||||
|
<source>Remove AmneziaWG from server?</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="279"/>
|
||||||
|
<source>All users who you shared a connection with will no longer be able to connect to it.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="280"/>
|
||||||
|
<source>Continue</source>
|
||||||
|
<translation type="unfinished">Продолжить</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="281"/>
|
||||||
|
<source>Cancel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="311"/>
|
||||||
|
<source>Save and Restart Amnezia</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>PageProtocolCloakSettings</name>
|
<name>PageProtocolCloakSettings</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -504,7 +592,7 @@ Already installed containers were found on the server. All installed containers
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageProtocolRaw.qml" line="130"/>
|
<location filename="../ui/qml/Pages2/PageProtocolRaw.qml" line="130"/>
|
||||||
<source>Connection options </source>
|
<source>Connection options %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -772,7 +860,7 @@ Already installed containers were found on the server. All installed containers
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettings.qml" line="100"/>
|
<location filename="../ui/qml/Pages2/PageSettings.qml" line="101"/>
|
||||||
<source>About AmneziaVPN</source>
|
<source>About AmneziaVPN</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -889,12 +977,7 @@ Already installed containers were found on the server. All installed containers
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="73"/>
|
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="73"/>
|
||||||
<source>Launch the application every time </source>
|
<source>Launch the application every time %1 starts</source>
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="73"/>
|
|
||||||
<source> starts</source>
|
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1061,21 +1144,21 @@ Already installed containers were found on the server. All installed containers
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="99"/>
|
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="99"/>
|
||||||
<source>Split site tunneling</source>
|
<source>Site-based split tunneling</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="100"/>
|
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="100"/>
|
||||||
<source>Allows you to choose which sites you want to use the VPN for.</source>
|
<source>Allows you to select which sites you want to access through the VPN</source>
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="113"/>
|
|
||||||
<source>Separate application tunneling</source>
|
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="114"/>
|
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="114"/>
|
||||||
|
<source>App-based split tunneling</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="115"/>
|
||||||
<source>Allows you to use the VPN only for certain applications</source>
|
<source>Allows you to use the VPN only for certain applications</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -1356,17 +1439,17 @@ Already installed containers were found on the server. All installed containers
|
||||||
<name>PageSettingsSplitTunneling</name>
|
<name>PageSettingsSplitTunneling</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="49"/>
|
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="49"/>
|
||||||
<source>Only the addresses in the list must be opened via VPN</source>
|
<source>Addresses from the list should be accessed via VPN</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="54"/>
|
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="54"/>
|
||||||
<source>Addresses from the list should never be opened via VPN</source>
|
<source>Addresses from the list should not be accessed via VPN</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="84"/>
|
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="84"/>
|
||||||
<source>Split site tunneling</source>
|
<source>Split tunneling</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -2288,103 +2371,109 @@ It's okay as long as it's from someone you trust.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="87"/>
|
<location filename="../containers/containers_defs.cpp" line="88"/>
|
||||||
<source>IPsec</source>
|
<source>IPsec</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="133"/>
|
<location filename="../containers/containers_defs.cpp" line="138"/>
|
||||||
<source>DNS Service</source>
|
<source>DNS Service</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="92"/>
|
<location filename="../containers/containers_defs.cpp" line="93"/>
|
||||||
<source>Sftp file sharing service</source>
|
<source>Sftp file sharing service</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="89"/>
|
<location filename="../containers/containers_defs.cpp" line="90"/>
|
||||||
<location filename="../containers/containers_defs.cpp" line="132"/>
|
<location filename="../containers/containers_defs.cpp" line="137"/>
|
||||||
<source>Website in Tor network</source>
|
<source>Website in Tor network</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="90"/>
|
<location filename="../containers/containers_defs.cpp" line="91"/>
|
||||||
<source>Amnezia DNS</source>
|
<source>Amnezia DNS</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="98"/>
|
<location filename="../containers/containers_defs.cpp" line="99"/>
|
||||||
<source>OpenVPN is the most popular VPN protocol, with flexible configuration options. It uses its own security protocol with SSL/TLS for key exchange.</source>
|
<source>OpenVPN is the most popular VPN protocol, with flexible configuration options. It uses its own security protocol with SSL/TLS for key exchange.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="101"/>
|
<location filename="../containers/containers_defs.cpp" line="102"/>
|
||||||
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but is recognised by analysis systems in some highly censored regions.</source>
|
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but is recognised by analysis systems in some highly censored regions.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="104"/>
|
<location filename="../containers/containers_defs.cpp" line="105"/>
|
||||||
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probbing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
|
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probbing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="108"/>
|
<location filename="../containers/containers_defs.cpp" line="109"/>
|
||||||
|
<location filename="../containers/containers_defs.cpp" line="112"/>
|
||||||
<source>WireGuard - New popular VPN protocol with high performance, high speed and low power consumption. Recommended for regions with low levels of censorship.</source>
|
<source>WireGuard - New popular VPN protocol with high performance, high speed and low power consumption. Recommended for regions with low levels of censorship.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="111"/>
|
<location filename="../containers/containers_defs.cpp" line="115"/>
|
||||||
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
<source>IKEv2 - Modern stable protocol, a bit faster than others, restores connection after signal loss. It has native support on the latest versions of Android and iOS.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="114"/>
|
<location filename="../containers/containers_defs.cpp" line="118"/>
|
||||||
<source>Deploy a WordPress site on the Tor network in two clicks.</source>
|
<source>Deploy a WordPress site on the Tor network in two clicks.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="116"/>
|
<location filename="../containers/containers_defs.cpp" line="120"/>
|
||||||
<source>Replace the current DNS server with your own. This will increase your privacy level.</source>
|
<source>Replace the current DNS server with your own. This will increase your privacy level.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="119"/>
|
<location filename="../containers/containers_defs.cpp" line="123"/>
|
||||||
<source>Creates a file vault on your server to securely store and transfer files.</source>
|
<source>Creates a file vault on your server to securely store and transfer files.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="124"/>
|
<location filename="../containers/containers_defs.cpp" line="128"/>
|
||||||
<source>OpenVPN container</source>
|
<source>OpenVPN container</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="125"/>
|
<location filename="../containers/containers_defs.cpp" line="129"/>
|
||||||
<source>Container with OpenVpn and ShadowSocks</source>
|
<source>Container with OpenVpn and ShadowSocks</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="127"/>
|
<location filename="../containers/containers_defs.cpp" line="131"/>
|
||||||
<source>Container with OpenVpn and ShadowSocks protocols configured with traffic masking by Cloak plugin</source>
|
<source>Container with OpenVpn and ShadowSocks protocols configured with traffic masking by Cloak plugin</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="129"/>
|
<location filename="../containers/containers_defs.cpp" line="133"/>
|
||||||
<source>WireGuard container</source>
|
<source>WireGuard container</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="130"/>
|
<location filename="../containers/containers_defs.cpp" line="134"/>
|
||||||
<source>IPsec container</source>
|
<source>AmneziaWG container</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="135"/>
|
<location filename="../containers/containers_defs.cpp" line="135"/>
|
||||||
|
<source>IPsec container</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../containers/containers_defs.cpp" line="140"/>
|
||||||
<source>Sftp file sharing service - is secure FTP service</source>
|
<source>Sftp file sharing service - is secure FTP service</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../protocols/protocols_defs.cpp" line="75"/>
|
<location filename="../protocols/protocols_defs.cpp" line="76"/>
|
||||||
<source>Sftp service</source>
|
<source>Sftp service</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -2448,16 +2537,6 @@ It's okay as long as it's from someone you trust.</source>
|
||||||
<source>error 0x%1: %2</source>
|
<source>error 0x%1: %2</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<location filename="../3rd/wireguard-tools/contrib/highlighter/gui/highlight.cpp" line="39"/>
|
|
||||||
<source>WireGuard Configuration Highlighter</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="../3rd/wireguard-tools/contrib/highlighter/gui/highlight.cpp" line="82"/>
|
|
||||||
<source>&Randomize colors</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SelectLanguageDrawer</name>
|
<name>SelectLanguageDrawer</name>
|
||||||
|
@ -2567,7 +2646,7 @@ It's okay as long as it's from someone you trust.</source>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../ui/controllers/sitesController.cpp" line="100"/>
|
<location filename="../ui/controllers/sitesController.cpp" line="100"/>
|
||||||
<source>The JSON data is not an array in file: </source>
|
<source>The JSON data is not an array in file: %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
|
@ -2614,6 +2693,14 @@ It's okay as long as it's from someone you trust.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>TextFieldWithHeaderType</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/qml/Controls2/TextFieldWithHeaderType.qml" line="105"/>
|
||||||
|
<source>The field can't be empty</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>VpnConnection</name>
|
<name>VpnConnection</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -2668,32 +2755,32 @@ It's okay as long as it's from someone you trust.</source>
|
||||||
<context>
|
<context>
|
||||||
<name>amnezia::ContainerProps</name>
|
<name>amnezia::ContainerProps</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="236"/>
|
<location filename="../containers/containers_defs.cpp" line="245"/>
|
||||||
<source>Low</source>
|
<source>Low</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="237"/>
|
<location filename="../containers/containers_defs.cpp" line="246"/>
|
||||||
<source>High</source>
|
<source>High</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="238"/>
|
<location filename="../containers/containers_defs.cpp" line="247"/>
|
||||||
<source>Medium</source>
|
<source>Medium</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="247"/>
|
<location filename="../containers/containers_defs.cpp" line="256"/>
|
||||||
<source>Many foreign websites and VPN providers are blocked</source>
|
<source>Many foreign websites and VPN providers are blocked</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="248"/>
|
<location filename="../containers/containers_defs.cpp" line="257"/>
|
||||||
<source>Some foreign sites are blocked, but VPN providers are not blocked</source>
|
<source>Some foreign sites are blocked, but VPN providers are not blocked</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../containers/containers_defs.cpp" line="246"/>
|
<location filename="../containers/containers_defs.cpp" line="255"/>
|
||||||
<source>I just want to increase the level of privacy</source>
|
<source>I just want to increase the level of privacy</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -214,21 +214,75 @@ QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
||||||
|
|
||||||
QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
{
|
{
|
||||||
|
QMap<QString, QString> configMap;
|
||||||
|
auto configByLines = data.split("\n");
|
||||||
|
for (const QString &line : configByLines) {
|
||||||
|
QString trimmedLine = line.trimmed();
|
||||||
|
if (trimmedLine.startsWith("[") && trimmedLine.endsWith("]")) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
QStringList parts = trimmedLine.split(" = ");
|
||||||
|
if (parts.count() == 2) {
|
||||||
|
configMap[parts.at(0).trimmed()] = parts.at(1).trimmed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QJsonObject lastConfig;
|
QJsonObject lastConfig;
|
||||||
lastConfig[config_key::config] = data;
|
lastConfig[config_key::config] = data;
|
||||||
|
|
||||||
const static QRegularExpression hostNameAndPortRegExp("Endpoint = (.*)(?::([0-9]*))?");
|
const static QRegularExpression hostNameAndPortRegExp("Endpoint = (.*):([0-9]*)");
|
||||||
QRegularExpressionMatch hostNameAndPortMatch = hostNameAndPortRegExp.match(data);
|
QRegularExpressionMatch hostNameAndPortMatch = hostNameAndPortRegExp.match(data);
|
||||||
QString hostName;
|
QString hostName;
|
||||||
QString port;
|
QString port;
|
||||||
if (hostNameAndPortMatch.hasCaptured(1)) {
|
if (hostNameAndPortMatch.hasCaptured(1)) {
|
||||||
hostName = hostNameAndPortMatch.captured(1);
|
hostName = hostNameAndPortMatch.captured(1);
|
||||||
} /*else {
|
} else {
|
||||||
qDebug() << "send error?"
|
qDebug() << "Failed to import profile";
|
||||||
}*/
|
emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError));
|
||||||
|
}
|
||||||
|
|
||||||
if (hostNameAndPortMatch.hasCaptured(2)) {
|
if (hostNameAndPortMatch.hasCaptured(2)) {
|
||||||
port = hostNameAndPortMatch.captured(2);
|
port = hostNameAndPortMatch.captured(2);
|
||||||
|
} else {
|
||||||
|
port = protocols::wireguard::defaultPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastConfig[config_key::hostName] = hostName;
|
||||||
|
lastConfig[config_key::port] = port.toInt();
|
||||||
|
|
||||||
|
// if (!configMap.value("PrivateKey").isEmpty() && !configMap.value("Address").isEmpty()
|
||||||
|
// && !configMap.value("PresharedKey").isEmpty() && !configMap.value("PublicKey").isEmpty()) {
|
||||||
|
lastConfig[config_key::client_priv_key] = configMap.value("PrivateKey");
|
||||||
|
lastConfig[config_key::client_ip] = configMap.value("Address");
|
||||||
|
lastConfig[config_key::psk_key] = configMap.value("PresharedKey");
|
||||||
|
lastConfig[config_key::server_pub_key] = configMap.value("PublicKey");
|
||||||
|
// } else {
|
||||||
|
// qDebug() << "Failed to import profile";
|
||||||
|
// emit importErrorOccurred(errorString(ErrorCode::ImportInvalidConfigError));
|
||||||
|
// return QJsonObject();
|
||||||
|
// }
|
||||||
|
|
||||||
|
QString protocolName = "wireguard";
|
||||||
|
if (!configMap.value(config_key::junkPacketCount).isEmpty()
|
||||||
|
&& !configMap.value(config_key::junkPacketMinSize).isEmpty()
|
||||||
|
&& !configMap.value(config_key::junkPacketMaxSize).isEmpty()
|
||||||
|
&& !configMap.value(config_key::initPacketJunkSize).isEmpty()
|
||||||
|
&& !configMap.value(config_key::responsePacketJunkSize).isEmpty()
|
||||||
|
&& !configMap.value(config_key::initPacketMagicHeader).isEmpty()
|
||||||
|
&& !configMap.value(config_key::responsePacketMagicHeader).isEmpty()
|
||||||
|
&& !configMap.value(config_key::underloadPacketMagicHeader).isEmpty()
|
||||||
|
&& !configMap.value(config_key::transportPacketMagicHeader).isEmpty()) {
|
||||||
|
lastConfig[config_key::junkPacketCount] = configMap.value(config_key::junkPacketCount);
|
||||||
|
lastConfig[config_key::junkPacketMinSize] = configMap.value(config_key::junkPacketMinSize);
|
||||||
|
lastConfig[config_key::junkPacketMaxSize] = configMap.value(config_key::junkPacketMaxSize);
|
||||||
|
lastConfig[config_key::initPacketJunkSize] = configMap.value(config_key::initPacketJunkSize);
|
||||||
|
lastConfig[config_key::responsePacketJunkSize] = configMap.value(config_key::responsePacketJunkSize);
|
||||||
|
lastConfig[config_key::initPacketMagicHeader] = configMap.value(config_key::initPacketMagicHeader);
|
||||||
|
lastConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
|
||||||
|
lastConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
||||||
|
lastConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
||||||
|
protocolName = "awg";
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject wireguardConfig;
|
QJsonObject wireguardConfig;
|
||||||
|
@ -238,15 +292,15 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
wireguardConfig[config_key::transport_proto] = "udp";
|
wireguardConfig[config_key::transport_proto] = "udp";
|
||||||
|
|
||||||
QJsonObject containers;
|
QJsonObject containers;
|
||||||
containers.insert(config_key::container, QJsonValue("amnezia-wireguard"));
|
containers.insert(config_key::container, QJsonValue("amnezia-" + protocolName));
|
||||||
containers.insert(config_key::wireguard, QJsonValue(wireguardConfig));
|
containers.insert(protocolName, QJsonValue(wireguardConfig));
|
||||||
|
|
||||||
QJsonArray arr;
|
QJsonArray arr;
|
||||||
arr.push_back(containers);
|
arr.push_back(containers);
|
||||||
|
|
||||||
QJsonObject config;
|
QJsonObject config;
|
||||||
config[config_key::containers] = arr;
|
config[config_key::containers] = arr;
|
||||||
config[config_key::defaultContainer] = "amnezia-wireguard";
|
config[config_key::defaultContainer] = "amnezia-" + protocolName;
|
||||||
config[config_key::description] = m_settings->nextAvailableServerName();
|
config[config_key::description] = m_settings->nextAvailableServerName();
|
||||||
|
|
||||||
const static QRegularExpression dnsRegExp(
|
const static QRegularExpression dnsRegExp(
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace PageLoader
|
||||||
PageProtocolShadowSocksSettings,
|
PageProtocolShadowSocksSettings,
|
||||||
PageProtocolCloakSettings,
|
PageProtocolCloakSettings,
|
||||||
PageProtocolWireGuardSettings,
|
PageProtocolWireGuardSettings,
|
||||||
|
PageProtocolAwgSettings,
|
||||||
PageProtocolIKev2Settings,
|
PageProtocolIKev2Settings,
|
||||||
PageProtocolRaw
|
PageProtocolRaw
|
||||||
};
|
};
|
||||||
|
|
|
@ -97,7 +97,7 @@ void SitesController::importSites(const QString &fileName, bool replaceExisting)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!jsonDocument.isArray()) {
|
if (!jsonDocument.isArray()) {
|
||||||
emit errorOccurred(tr("The JSON data is not an array in file: ").arg(fileName));
|
emit errorOccurred(tr("The JSON data is not an array in file: %1").arg(fileName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
137
client/ui/models/protocols/awgConfigModel.cpp
Normal file
137
client/ui/models/protocols/awgConfigModel.cpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
#include "awgConfigModel.h"
|
||||||
|
|
||||||
|
#include <QJsonDocument>
|
||||||
|
|
||||||
|
#include "protocols/protocols_defs.h"
|
||||||
|
|
||||||
|
AwgConfigModel::AwgConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int AwgConfigModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (!index.isValid() || index.row() < 0 || index.row() >= ContainerProps::allContainers().size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
||||||
|
case Roles::JunkPacketCountRole: m_protocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
|
||||||
|
case Roles::JunkPacketMinSizeRole: m_protocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
|
||||||
|
case Roles::JunkPacketMaxSizeRole: m_protocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
|
||||||
|
case Roles::InitPacketJunkSizeRole:
|
||||||
|
m_protocolConfig.insert(config_key::initPacketJunkSize, value.toString());
|
||||||
|
break;
|
||||||
|
case Roles::ResponsePacketJunkSizeRole:
|
||||||
|
m_protocolConfig.insert(config_key::responsePacketJunkSize, value.toString());
|
||||||
|
break;
|
||||||
|
case Roles::InitPacketMagicHeaderRole:
|
||||||
|
m_protocolConfig.insert(config_key::initPacketMagicHeader, value.toString());
|
||||||
|
break;
|
||||||
|
case Roles::ResponsePacketMagicHeaderRole:
|
||||||
|
m_protocolConfig.insert(config_key::responsePacketMagicHeader, value.toString());
|
||||||
|
break;
|
||||||
|
case Roles::UnderloadPacketMagicHeaderRole:
|
||||||
|
m_protocolConfig.insert(config_key::underloadPacketMagicHeader, value.toString());
|
||||||
|
break;
|
||||||
|
case Roles::TransportPacketMagicHeaderRole:
|
||||||
|
m_protocolConfig.insert(config_key::transportPacketMagicHeader, value.toString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit dataChanged(index, index, QList { role });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
|
||||||
|
case Roles::JunkPacketCountRole: return m_protocolConfig.value(config_key::junkPacketCount);
|
||||||
|
case Roles::JunkPacketMinSizeRole: return m_protocolConfig.value(config_key::junkPacketMinSize);
|
||||||
|
case Roles::JunkPacketMaxSizeRole: return m_protocolConfig.value(config_key::junkPacketMaxSize);
|
||||||
|
case Roles::InitPacketJunkSizeRole: return m_protocolConfig.value(config_key::initPacketJunkSize);
|
||||||
|
case Roles::ResponsePacketJunkSizeRole: return m_protocolConfig.value(config_key::responsePacketJunkSize);
|
||||||
|
case Roles::InitPacketMagicHeaderRole: return m_protocolConfig.value(config_key::initPacketMagicHeader);
|
||||||
|
case Roles::ResponsePacketMagicHeaderRole: return m_protocolConfig.value(config_key::responsePacketMagicHeader);
|
||||||
|
case Roles::UnderloadPacketMagicHeaderRole: return m_protocolConfig.value(config_key::underloadPacketMagicHeader);
|
||||||
|
case Roles::TransportPacketMagicHeaderRole: return m_protocolConfig.value(config_key::transportPacketMagicHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AwgConfigModel::updateModel(const QJsonObject &config)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||||
|
|
||||||
|
m_fullConfig = config;
|
||||||
|
|
||||||
|
QJsonObject protocolConfig = config.value(config_key::awg).toObject();
|
||||||
|
|
||||||
|
m_protocolConfig[config_key::port] =
|
||||||
|
protocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
||||||
|
m_protocolConfig[config_key::junkPacketCount] =
|
||||||
|
protocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
||||||
|
m_protocolConfig[config_key::junkPacketMinSize] =
|
||||||
|
protocolConfig.value(config_key::junkPacketMinSize)
|
||||||
|
.toString(protocols::awg::defaultJunkPacketMinSize);
|
||||||
|
m_protocolConfig[config_key::junkPacketMaxSize] =
|
||||||
|
protocolConfig.value(config_key::junkPacketMaxSize)
|
||||||
|
.toString(protocols::awg::defaultJunkPacketMaxSize);
|
||||||
|
m_protocolConfig[config_key::initPacketJunkSize] =
|
||||||
|
protocolConfig.value(config_key::initPacketJunkSize)
|
||||||
|
.toString(protocols::awg::defaultInitPacketJunkSize);
|
||||||
|
m_protocolConfig[config_key::responsePacketJunkSize] =
|
||||||
|
protocolConfig.value(config_key::responsePacketJunkSize)
|
||||||
|
.toString(protocols::awg::defaultResponsePacketJunkSize);
|
||||||
|
m_protocolConfig[config_key::initPacketMagicHeader] =
|
||||||
|
protocolConfig.value(config_key::initPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultInitPacketMagicHeader);
|
||||||
|
m_protocolConfig[config_key::responsePacketMagicHeader] =
|
||||||
|
protocolConfig.value(config_key::responsePacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultResponsePacketMagicHeader);
|
||||||
|
m_protocolConfig[config_key::underloadPacketMagicHeader] =
|
||||||
|
protocolConfig.value(config_key::underloadPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultUnderloadPacketMagicHeader);
|
||||||
|
m_protocolConfig[config_key::transportPacketMagicHeader] =
|
||||||
|
protocolConfig.value(config_key::transportPacketMagicHeader)
|
||||||
|
.toString(protocols::awg::defaultTransportPacketMagicHeader);
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject AwgConfigModel::getConfig()
|
||||||
|
{
|
||||||
|
m_fullConfig.insert(config_key::awg, m_protocolConfig);
|
||||||
|
return m_fullConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> AwgConfigModel::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
|
roles[PortRole] = "port";
|
||||||
|
roles[JunkPacketCountRole] = "junkPacketCount";
|
||||||
|
roles[JunkPacketMinSizeRole] = "junkPacketMinSize";
|
||||||
|
roles[JunkPacketMaxSizeRole] = "junkPacketMaxSize";
|
||||||
|
roles[InitPacketJunkSizeRole] = "initPacketJunkSize";
|
||||||
|
roles[ResponsePacketJunkSizeRole] = "responsePacketJunkSize";
|
||||||
|
roles[InitPacketMagicHeaderRole] = "initPacketMagicHeader";
|
||||||
|
roles[ResponsePacketMagicHeaderRole] = "responsePacketMagicHeader";
|
||||||
|
roles[UnderloadPacketMagicHeaderRole] = "underloadPacketMagicHeader";
|
||||||
|
roles[TransportPacketMagicHeaderRole] = "transportPacketMagicHeader";
|
||||||
|
|
||||||
|
return roles;
|
||||||
|
}
|
47
client/ui/models/protocols/awgConfigModel.h
Normal file
47
client/ui/models/protocols/awgConfigModel.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef AWGCONFIGMODEL_H
|
||||||
|
#define AWGCONFIGMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
|
class AwgConfigModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Roles {
|
||||||
|
PortRole = Qt::UserRole + 1,
|
||||||
|
JunkPacketCountRole,
|
||||||
|
JunkPacketMinSizeRole,
|
||||||
|
JunkPacketMaxSizeRole,
|
||||||
|
InitPacketJunkSizeRole,
|
||||||
|
ResponsePacketJunkSizeRole,
|
||||||
|
InitPacketMagicHeaderRole,
|
||||||
|
ResponsePacketMagicHeaderRole,
|
||||||
|
UnderloadPacketMagicHeaderRole,
|
||||||
|
TransportPacketMagicHeaderRole
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit AwgConfigModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateModel(const QJsonObject &config);
|
||||||
|
QJsonObject getConfig();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DockerContainer m_container;
|
||||||
|
QJsonObject m_protocolConfig;
|
||||||
|
QJsonObject m_fullConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AWGCONFIGMODEL_H
|
|
@ -72,8 +72,7 @@ ListView {
|
||||||
containersDropDown.menuVisible = false
|
containersDropDown.menuVisible = false
|
||||||
|
|
||||||
|
|
||||||
if (needReconnected &&
|
if (needReconnected && (ConnectionController.isConnected || ConnectionController.isConnectionInProgress)) {
|
||||||
(ConnectionController.isConnected || ConnectionController.isConnectionInProgress)) {
|
|
||||||
PageController.showNotificationMessage(qsTr("Reconnect via VPN Procotol: ") + name)
|
PageController.showNotificationMessage(qsTr("Reconnect via VPN Procotol: ") + name)
|
||||||
PageController.goToPageHome()
|
PageController.goToPageHome()
|
||||||
ConnectionController.openConnection()
|
ConnectionController.openConnection()
|
||||||
|
|
|
@ -64,6 +64,11 @@ ListView {
|
||||||
// goToPage(PageEnum.PageProtocolWireGuardSettings)
|
// goToPage(PageEnum.PageProtocolWireGuardSettings)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case ContainerEnum.Awg: {
|
||||||
|
AwgConfigModel.updateModel(config)
|
||||||
|
PageController.goToPage(PageEnum.PageProtocolAwgSettings)
|
||||||
|
break
|
||||||
|
}
|
||||||
case ContainerEnum.Ipsec: {
|
case ContainerEnum.Ipsec: {
|
||||||
ProtocolsModel.updateModel(config)
|
ProtocolsModel.updateModel(config)
|
||||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||||
|
|
|
@ -12,6 +12,7 @@ Item {
|
||||||
property string headerTextColor: "#878b91"
|
property string headerTextColor: "#878b91"
|
||||||
|
|
||||||
property alias errorText: errorField.text
|
property alias errorText: errorField.text
|
||||||
|
property bool checkEmptyText: false
|
||||||
|
|
||||||
property string buttonText
|
property string buttonText
|
||||||
property string buttonImageSource
|
property string buttonImageSource
|
||||||
|
@ -99,6 +100,12 @@ Item {
|
||||||
root.errorText = ""
|
root.errorText = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (checkEmptyText && textFieldText === "") {
|
||||||
|
errorText = qsTr("The field can't be empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
acceptedButtons: Qt.RightButton
|
acceptedButtons: Qt.RightButton
|
||||||
|
|
329
client/ui/qml/Pages2/PageProtocolAwgSettings.qml
Normal file
329
client/ui/qml/Pages2/PageProtocolAwgSettings.qml
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
|
||||||
|
import "./"
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Controls2/TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
import "../Components"
|
||||||
|
|
||||||
|
PageType {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlickableType {
|
||||||
|
id: fl
|
||||||
|
anchors.top: backButton.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listview
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: listview.contentItem.height
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
interactive: false
|
||||||
|
|
||||||
|
model: AwgConfigModel
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
implicitWidth: listview.width
|
||||||
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: col
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
HeaderType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
headerText: qsTr("AmneziaWG settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: portTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 40
|
||||||
|
|
||||||
|
headerText: qsTr("Port")
|
||||||
|
textFieldText: port
|
||||||
|
textField.maximumLength: 5
|
||||||
|
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== port) {
|
||||||
|
port = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: junkPacketCountTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Junk packet count")
|
||||||
|
textFieldText: junkPacketCount
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
console.log("1")
|
||||||
|
if (textFieldText === "") {
|
||||||
|
textFieldText = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textFieldText !== junkPacketCount) {
|
||||||
|
junkPacketCount = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: junkPacketMinSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Junk packet minimum size")
|
||||||
|
textFieldText: junkPacketMinSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== junkPacketMinSize) {
|
||||||
|
junkPacketMinSize = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: junkPacketMaxSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Junk packet maximum size")
|
||||||
|
textFieldText: junkPacketMaxSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== junkPacketMaxSize) {
|
||||||
|
junkPacketMaxSize = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: initPacketJunkSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Init packet junk size")
|
||||||
|
textFieldText: initPacketJunkSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== initPacketJunkSize) {
|
||||||
|
initPacketJunkSize = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: responsePacketJunkSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Response packet junk size")
|
||||||
|
textFieldText: responsePacketJunkSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== responsePacketJunkSize) {
|
||||||
|
responsePacketJunkSize = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: initPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Init packet magic header")
|
||||||
|
textFieldText: initPacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== initPacketMagicHeader) {
|
||||||
|
initPacketMagicHeader = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: responsePacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Response packet magic header")
|
||||||
|
textFieldText: responsePacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== responsePacketMagicHeader) {
|
||||||
|
responsePacketMagicHeader = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: transportPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Transport packet magic header")
|
||||||
|
textFieldText: transportPacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== transportPacketMagicHeader) {
|
||||||
|
transportPacketMagicHeader = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: underloadPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Underload packet magic header")
|
||||||
|
textFieldText: underloadPacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textFieldText !== underloadPacketMagicHeader) {
|
||||||
|
underloadPacketMagicHeader = textFieldText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.leftMargin: -8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
text: qsTr("Remove AmneziaWG")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
questionDrawer.headerText = qsTr("Remove AmneziaWG from server?")
|
||||||
|
questionDrawer.descriptionText = qsTr("All users who you shared a connection with will no longer be able to connect to it.")
|
||||||
|
questionDrawer.yesButtonText = qsTr("Continue")
|
||||||
|
questionDrawer.noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
|
questionDrawer.yesButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
|
InstallController.removeCurrentlyProcessedContainer()
|
||||||
|
}
|
||||||
|
questionDrawer.noButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
}
|
||||||
|
questionDrawer.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
|
enabled: underloadPacketMagicHeaderTextField.errorText === "" &&
|
||||||
|
transportPacketMagicHeaderTextField.errorText === "" &&
|
||||||
|
responsePacketMagicHeaderTextField.errorText === "" &&
|
||||||
|
initPacketMagicHeaderTextField.errorText === "" &&
|
||||||
|
responsePacketJunkSizeTextField.errorText === "" &&
|
||||||
|
initPacketJunkSizeTextField.errorText === "" &&
|
||||||
|
junkPacketMaxSizeTextField.errorText === "" &&
|
||||||
|
junkPacketMinSizeTextField.errorText === "" &&
|
||||||
|
junkPacketCountTextField.errorText === "" &&
|
||||||
|
portTextField.errorText === ""
|
||||||
|
|
||||||
|
text: qsTr("Save and Restart Amnezia")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
forceActiveFocus()
|
||||||
|
PageController.showBusyIndicator(true)
|
||||||
|
InstallController.updateContainer(AwgConfigModel.getConfig())
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionDrawer {
|
||||||
|
id: questionDrawer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,7 +127,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Connection options ") + protocolName
|
headerText: qsTr("Connection options %1").arg(protocolName)
|
||||||
}
|
}
|
||||||
|
|
||||||
TextArea {
|
TextArea {
|
||||||
|
|
|
@ -95,6 +95,7 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: about
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("About AmneziaVPN")
|
text: qsTr("About AmneziaVPN")
|
||||||
|
@ -111,6 +112,7 @@ PageType {
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
visible: GC.isMobile()
|
visible: GC.isMobile()
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: about.height
|
||||||
|
|
||||||
text: qsTr("Close application")
|
text: qsTr("Close application")
|
||||||
leftImageSource: "qrc:/images/controls/x-circle.svg"
|
leftImageSource: "qrc:/images/controls/x-circle.svg"
|
||||||
|
|
|
@ -70,7 +70,7 @@ PageType {
|
||||||
Layout.margins: 16
|
Layout.margins: 16
|
||||||
|
|
||||||
text: qsTr("Auto start")
|
text: qsTr("Auto start")
|
||||||
descriptionText: qsTr("Launch the application every time ") + Qt.platform.os + qsTr(" starts")
|
descriptionText: qsTr("Launch the application every time %1 starts").arg(Qt.platform.os)
|
||||||
|
|
||||||
checked: SettingsController.isAutoStartEnabled()
|
checked: SettingsController.isAutoStartEnabled()
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
|
|
|
@ -98,8 +98,8 @@ PageType {
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Split site tunneling")
|
text: qsTr("Site-based split tunneling")
|
||||||
descriptionText: qsTr("Allows you to choose which sites you want to use the VPN for.")
|
descriptionText: qsTr("Allows you to select which sites you want to access through the VPN")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
|
@ -115,8 +115,9 @@ PageType {
|
||||||
visible: !GC.isMobile()
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
text: qsTr("Separate application tunneling")
|
text: qsTr("App-based split tunneling")
|
||||||
descriptionText: qsTr("Allows you to use the VPN only for certain applications")
|
descriptionText: qsTr("Allows you to use the VPN only for certain applications")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
|
|
@ -50,12 +50,12 @@ PageType {
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: onlyForwardSites
|
id: onlyForwardSites
|
||||||
property string name: qsTr("Only the addresses in the list must be opened via VPN")
|
property string name: qsTr("Addresses from the list should be accessed via VPN")
|
||||||
property int type: routeMode.onlyForwardSites
|
property int type: routeMode.onlyForwardSites
|
||||||
}
|
}
|
||||||
QtObject {
|
QtObject {
|
||||||
id: allExceptSites
|
id: allExceptSites
|
||||||
property string name: qsTr("Addresses from the list should never be opened via VPN")
|
property string name: qsTr("Addresses from the list should not be accessed via VPN")
|
||||||
property int type: routeMode.allExceptSites
|
property int type: routeMode.allExceptSites
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Split site tunneling")
|
headerText: qsTr("Split tunneling")
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
|
|
@ -62,7 +62,7 @@ PageType {
|
||||||
function onInstallationErrorOccurred(errorMessage) {
|
function onInstallationErrorOccurred(errorMessage) {
|
||||||
PageController.showErrorMessage(errorMessage)
|
PageController.showErrorMessage(errorMessage)
|
||||||
|
|
||||||
var currentPageName = tabBarStackView.currentItem.objectName
|
var currentPageName = stackView.currentItem.objectName
|
||||||
|
|
||||||
if (currentPageName === PageController.getPagePath(PageEnum.PageSetupWizardInstalling)) {
|
if (currentPageName === PageController.getPagePath(PageEnum.PageSetupWizardInstalling)) {
|
||||||
PageController.closePage()
|
PageController.closePage()
|
||||||
|
|
|
@ -320,7 +320,7 @@ PageType {
|
||||||
|
|
||||||
if (index === ContainerProps.containerFromString("amnezia-openvpn")) {
|
if (index === ContainerProps.containerFromString("amnezia-openvpn")) {
|
||||||
root.connectionTypesModel.push(openVpnConnectionFormat)
|
root.connectionTypesModel.push(openVpnConnectionFormat)
|
||||||
} else if (index === ContainerProps.containerFromString("amnezia-wireguard")) {
|
} else if (index === ContainerProps.containerFromString("amnezia-awg")) {
|
||||||
root.connectionTypesModel.push(wireGuardConnectionFormat)
|
root.connectionTypesModel.push(wireGuardConnectionFormat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ cd %PROJECT_DIR%
|
||||||
call "%QT_BIN_DIR:"=%\qt-cmake" . -B %WORK_DIR%
|
call "%QT_BIN_DIR:"=%\qt-cmake" . -B %WORK_DIR%
|
||||||
|
|
||||||
cd %WORK_DIR%
|
cd %WORK_DIR%
|
||||||
cmake --build . --config release
|
cmake --build . --config release -- /p:UseMultiToolTask=true /m
|
||||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||||
|
|
||||||
cmake --build . --target clean
|
cmake --build . --target clean
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue