Compare commits
1 commit
dev
...
bugfix/win
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9106b8be34 |
166 changed files with 2311 additions and 5304 deletions
84
.github/workflows/deploy.yml
vendored
84
.github/workflows/deploy.yml
vendored
|
|
@ -20,8 +20,6 @@ jobs:
|
||||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
|
||||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 'Install Qt'
|
- name: 'Install Qt'
|
||||||
|
|
@ -92,8 +90,6 @@ jobs:
|
||||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
|
||||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 'Get sources'
|
- name: 'Get sources'
|
||||||
|
|
@ -160,8 +156,6 @@ jobs:
|
||||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
|
||||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 'Setup xcode'
|
- name: 'Setup xcode'
|
||||||
|
|
@ -249,82 +243,18 @@ jobs:
|
||||||
|
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
|
|
||||||
Build-MacOS-old:
|
Build-MacOS:
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
|
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
|
||||||
QT_VERSION: 6.4.3
|
QT_VERSION: 6.4.3
|
||||||
|
QIF_VERSION: 4.6
|
||||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||||
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
||||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
|
||||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 'Setup xcode'
|
|
||||||
uses: maxim-lobanov/setup-xcode@v1
|
|
||||||
with:
|
|
||||||
xcode-version: '15.4.0'
|
|
||||||
|
|
||||||
- name: 'Install Qt'
|
|
||||||
uses: jurplel/install-qt-action@v3
|
|
||||||
with:
|
|
||||||
version: ${{ env.QT_VERSION }}
|
|
||||||
host: 'mac'
|
|
||||||
target: 'desktop'
|
|
||||||
arch: 'clang_64'
|
|
||||||
modules: 'qtremoteobjects qt5compat qtshadertools'
|
|
||||||
dir: ${{ runner.temp }}
|
|
||||||
setup-python: 'true'
|
|
||||||
set-env: 'true'
|
|
||||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
|
||||||
|
|
||||||
|
|
||||||
- name: 'Get sources'
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: 'true'
|
|
||||||
fetch-depth: 10
|
|
||||||
|
|
||||||
- name: 'Setup ccache'
|
|
||||||
uses: hendrikmuhs/ccache-action@v1.2
|
|
||||||
|
|
||||||
- name: 'Build project'
|
|
||||||
run: |
|
|
||||||
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
|
||||||
bash deploy/build_macos.sh
|
|
||||||
|
|
||||||
- name: 'Upload installer artifact'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: AmneziaVPN_MacOS_old_installer
|
|
||||||
path: deploy/build/pkg/AmneziaVPN.pkg
|
|
||||||
retention-days: 7
|
|
||||||
|
|
||||||
- name: 'Upload unpacked artifact'
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: AmneziaVPN_MacOS_old_unpacked
|
|
||||||
path: deploy/build/client/AmneziaVPN.app
|
|
||||||
retention-days: 7
|
|
||||||
|
|
||||||
# ------------------------------------------------------
|
|
||||||
|
|
||||||
Build-MacOS:
|
|
||||||
runs-on: macos-latest
|
|
||||||
|
|
||||||
env:
|
|
||||||
QT_VERSION: 6.8.0
|
|
||||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
|
||||||
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
|
|
||||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
|
||||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
|
||||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
|
||||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
|
||||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 'Setup xcode'
|
- name: 'Setup xcode'
|
||||||
|
|
@ -345,6 +275,11 @@ jobs:
|
||||||
set-env: 'true'
|
set-env: 'true'
|
||||||
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
|
||||||
|
|
||||||
|
- name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}'
|
||||||
|
run: |
|
||||||
|
mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework
|
||||||
|
wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip
|
||||||
|
unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/
|
||||||
|
|
||||||
- name: 'Get sources'
|
- name: 'Get sources'
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -358,13 +293,14 @@ jobs:
|
||||||
- name: 'Build project'
|
- name: 'Build project'
|
||||||
run: |
|
run: |
|
||||||
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
|
||||||
|
export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin"
|
||||||
bash deploy/build_macos.sh
|
bash deploy/build_macos.sh
|
||||||
|
|
||||||
- name: 'Upload installer artifact'
|
- name: 'Upload installer artifact'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: AmneziaVPN_MacOS_installer
|
name: AmneziaVPN_MacOS_installer
|
||||||
path: deploy/build/pkg/AmneziaVPN.pkg
|
path: AmneziaVPN.dmg
|
||||||
retention-days: 7
|
retention-days: 7
|
||||||
|
|
||||||
- name: 'Upload unpacked artifact'
|
- name: 'Upload unpacked artifact'
|
||||||
|
|
@ -388,8 +324,6 @@ jobs:
|
||||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
|
||||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 'Install desktop Qt'
|
- name: 'Install desktop Qt'
|
||||||
|
|
|
||||||
2
.github/workflows/tag-deploy.yml
vendored
2
.github/workflows/tag-deploy.yml
vendored
|
|
@ -20,8 +20,6 @@ jobs:
|
||||||
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
|
||||||
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
|
||||||
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
|
||||||
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
|
|
||||||
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: 'Install desktop Qt'
|
- name: 'Install desktop Qt'
|
||||||
|
|
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -133,8 +133,4 @@ client/3rd/ShadowSocks/ss_ios.xcconfig
|
||||||
out/
|
out/
|
||||||
|
|
||||||
# CMake files
|
# CMake files
|
||||||
CMakeFiles/
|
CMakeFiles/
|
||||||
|
|
||||||
ios-ne-build.sh
|
|
||||||
macos-ne-build.sh
|
|
||||||
macos-signed-build.sh
|
|
||||||
1
.gitmodules
vendored
1
.gitmodules
vendored
|
|
@ -7,7 +7,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
|
||||||
branch = feature/special-handshake
|
|
||||||
[submodule "client/3rd/amneziawg-apple"]
|
[submodule "client/3rd/amneziawg-apple"]
|
||||||
path = client/3rd/amneziawg-apple
|
path = client/3rd/amneziawg-apple
|
||||||
url = https://github.com/amnezia-vpn/amneziawg-apple
|
url = https://github.com/amnezia-vpn/amneziawg-apple
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||||
|
|
||||||
set(PROJECT AmneziaVPN)
|
set(PROJECT AmneziaVPN)
|
||||||
|
|
||||||
project(${PROJECT} VERSION 4.8.8.1
|
project(${PROJECT} VERSION 4.8.6.0
|
||||||
DESCRIPTION "AmneziaVPN"
|
DESCRIPTION "AmneziaVPN"
|
||||||
HOMEPAGE_URL "https://amnezia.org/"
|
HOMEPAGE_URL "https://amnezia.org/"
|
||||||
)
|
)
|
||||||
|
|
@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||||
|
|
||||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||||
set(APP_ANDROID_VERSION_CODE 2087)
|
set(APP_ANDROID_VERSION_CODE 2083)
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||||
set(MZ_PLATFORM_NAME "linux")
|
set(MZ_PLATFORM_NAME "linux")
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 840b7b070e6ac8b90dda2fac6e98859b23727c0c
|
Subproject commit efad1a5b5cb8e8ab61e49ccdca18c9090a0da8d3
|
||||||
2
client/3rd/amneziawg-apple
vendored
2
client/3rd/amneziawg-apple
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit 811af0a83b3faeade89a9093a588595666d32066
|
Subproject commit 76e7db556a6d7e2582f9481df91db188a46c009c
|
||||||
|
|
@ -31,9 +31,6 @@ add_definitions(-DDEV_AGW_PUBLIC_KEY="$ENV{DEV_AGW_PUBLIC_KEY}")
|
||||||
add_definitions(-DDEV_AGW_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}")
|
add_definitions(-DDEV_AGW_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}")
|
||||||
add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
|
add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
|
||||||
|
|
||||||
add_definitions(-DFREE_V2_ENDPOINT="$ENV{FREE_V2_ENDPOINT}")
|
|
||||||
add_definitions(-DPREM_V1_ENDPOINT="$ENV{PREM_V1_ENDPOINT}")
|
|
||||||
|
|
||||||
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||||
set(PACKAGES ${PACKAGES} Widgets)
|
set(PACKAGES ${PACKAGES} Widgets)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -120,21 +120,10 @@ open class Wireguard : Protocol() {
|
||||||
configData.optStringOrNull("Jmax")?.let { setJmax(it.toInt()) }
|
configData.optStringOrNull("Jmax")?.let { setJmax(it.toInt()) }
|
||||||
configData.optStringOrNull("S1")?.let { setS1(it.toInt()) }
|
configData.optStringOrNull("S1")?.let { setS1(it.toInt()) }
|
||||||
configData.optStringOrNull("S2")?.let { setS2(it.toInt()) }
|
configData.optStringOrNull("S2")?.let { setS2(it.toInt()) }
|
||||||
configData.optStringOrNull("S3")?.let { setS3(it.toInt()) }
|
|
||||||
configData.optStringOrNull("S4")?.let { setS4(it.toInt()) }
|
|
||||||
configData.optStringOrNull("H1")?.let { setH1(it.toLong()) }
|
configData.optStringOrNull("H1")?.let { setH1(it.toLong()) }
|
||||||
configData.optStringOrNull("H2")?.let { setH2(it.toLong()) }
|
configData.optStringOrNull("H2")?.let { setH2(it.toLong()) }
|
||||||
configData.optStringOrNull("H3")?.let { setH3(it.toLong()) }
|
configData.optStringOrNull("H3")?.let { setH3(it.toLong()) }
|
||||||
configData.optStringOrNull("H4")?.let { setH4(it.toLong()) }
|
configData.optStringOrNull("H4")?.let { setH4(it.toLong()) }
|
||||||
configData.optStringOrNull("I1")?.let { setI1(it) }
|
|
||||||
configData.optStringOrNull("I2")?.let { setI2(it) }
|
|
||||||
configData.optStringOrNull("I3")?.let { setI3(it) }
|
|
||||||
configData.optStringOrNull("I4")?.let { setI4(it) }
|
|
||||||
configData.optStringOrNull("I5")?.let { setI5(it) }
|
|
||||||
configData.optStringOrNull("J1")?.let { setJ1(it) }
|
|
||||||
configData.optStringOrNull("J2")?.let { setJ2(it) }
|
|
||||||
configData.optStringOrNull("J3")?.let { setJ3(it) }
|
|
||||||
configData.optStringOrNull("Itime")?.let { setItime(it.toInt()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun start(config: WireguardConfig, vpnBuilder: Builder, protect: (Int) -> Boolean) {
|
private fun start(config: WireguardConfig, vpnBuilder: Builder, protect: (Int) -> Boolean) {
|
||||||
|
|
|
||||||
|
|
@ -20,21 +20,10 @@ open class WireguardConfig protected constructor(
|
||||||
val jmax: Int?,
|
val jmax: Int?,
|
||||||
val s1: Int?,
|
val s1: Int?,
|
||||||
val s2: Int?,
|
val s2: Int?,
|
||||||
val s3: Int?,
|
|
||||||
val s4: Int?,
|
|
||||||
val h1: Long?,
|
val h1: Long?,
|
||||||
val h2: Long?,
|
val h2: Long?,
|
||||||
val h3: Long?,
|
val h3: Long?,
|
||||||
val h4: Long?,
|
val h4: Long?
|
||||||
var i1: String?,
|
|
||||||
var i2: String?,
|
|
||||||
var i3: String?,
|
|
||||||
var i4: String?,
|
|
||||||
var i5: String?,
|
|
||||||
var j1: String?,
|
|
||||||
var j2: String?,
|
|
||||||
var j3: String?,
|
|
||||||
var itime: Int?
|
|
||||||
) : ProtocolConfig(protocolConfigBuilder) {
|
) : ProtocolConfig(protocolConfigBuilder) {
|
||||||
|
|
||||||
protected constructor(builder: Builder) : this(
|
protected constructor(builder: Builder) : this(
|
||||||
|
|
@ -50,21 +39,10 @@ open class WireguardConfig protected constructor(
|
||||||
builder.jmax,
|
builder.jmax,
|
||||||
builder.s1,
|
builder.s1,
|
||||||
builder.s2,
|
builder.s2,
|
||||||
builder.s3,
|
|
||||||
builder.s4,
|
|
||||||
builder.h1,
|
builder.h1,
|
||||||
builder.h2,
|
builder.h2,
|
||||||
builder.h3,
|
builder.h3,
|
||||||
builder.h4,
|
builder.h4
|
||||||
builder.i1,
|
|
||||||
builder.i2,
|
|
||||||
builder.i3,
|
|
||||||
builder.i4,
|
|
||||||
builder.i5,
|
|
||||||
builder.j1,
|
|
||||||
builder.j2,
|
|
||||||
builder.j3,
|
|
||||||
builder.itime
|
|
||||||
)
|
)
|
||||||
|
|
||||||
fun toWgUserspaceString(): String = with(StringBuilder()) {
|
fun toWgUserspaceString(): String = with(StringBuilder()) {
|
||||||
|
|
@ -83,21 +61,10 @@ open class WireguardConfig protected constructor(
|
||||||
appendLine("jmax=$jmax")
|
appendLine("jmax=$jmax")
|
||||||
appendLine("s1=$s1")
|
appendLine("s1=$s1")
|
||||||
appendLine("s2=$s2")
|
appendLine("s2=$s2")
|
||||||
s3?.let { appendLine("s3=$it") }
|
|
||||||
s4?.let { appendLine("s4=$it") }
|
|
||||||
appendLine("h1=$h1")
|
appendLine("h1=$h1")
|
||||||
appendLine("h2=$h2")
|
appendLine("h2=$h2")
|
||||||
appendLine("h3=$h3")
|
appendLine("h3=$h3")
|
||||||
appendLine("h4=$h4")
|
appendLine("h4=$h4")
|
||||||
i1?.let { appendLine("i1=$it") }
|
|
||||||
i2?.let { appendLine("i2=$it") }
|
|
||||||
i3?.let { appendLine("i3=$it") }
|
|
||||||
i4?.let { appendLine("i4=$it") }
|
|
||||||
i5?.let { appendLine("i5=$it") }
|
|
||||||
j1?.let { appendLine("j1=$it") }
|
|
||||||
j2?.let { appendLine("j2=$it") }
|
|
||||||
j3?.let { appendLine("j3=$it") }
|
|
||||||
itime?.let { appendLine("itime=$it") }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,21 +117,10 @@ open class WireguardConfig protected constructor(
|
||||||
internal var jmax: Int? = null
|
internal var jmax: Int? = null
|
||||||
internal var s1: Int? = null
|
internal var s1: Int? = null
|
||||||
internal var s2: Int? = null
|
internal var s2: Int? = null
|
||||||
internal var s3: Int? = null
|
|
||||||
internal var s4: Int? = null
|
|
||||||
internal var h1: Long? = null
|
internal var h1: Long? = null
|
||||||
internal var h2: Long? = null
|
internal var h2: Long? = null
|
||||||
internal var h3: Long? = null
|
internal var h3: Long? = null
|
||||||
internal var h4: Long? = null
|
internal var h4: Long? = null
|
||||||
internal var i1: String? = null
|
|
||||||
internal var i2: String? = null
|
|
||||||
internal var i3: String? = null
|
|
||||||
internal var i4: String? = null
|
|
||||||
internal var i5: String? = null
|
|
||||||
internal var j1: String? = null
|
|
||||||
internal var j2: String? = null
|
|
||||||
internal var j3: String? = null
|
|
||||||
internal var itime: Int? = null
|
|
||||||
|
|
||||||
fun setEndpoint(endpoint: InetEndpoint) = apply { this.endpoint = endpoint }
|
fun setEndpoint(endpoint: InetEndpoint) = apply { this.endpoint = endpoint }
|
||||||
|
|
||||||
|
|
@ -183,21 +139,10 @@ open class WireguardConfig protected constructor(
|
||||||
fun setJmax(jmax: Int) = apply { this.jmax = jmax }
|
fun setJmax(jmax: Int) = apply { this.jmax = jmax }
|
||||||
fun setS1(s1: Int) = apply { this.s1 = s1 }
|
fun setS1(s1: Int) = apply { this.s1 = s1 }
|
||||||
fun setS2(s2: Int) = apply { this.s2 = s2 }
|
fun setS2(s2: Int) = apply { this.s2 = s2 }
|
||||||
fun setS3(s3: Int) = apply { this.s3 = s3 }
|
|
||||||
fun setS4(s4: Int) = apply { this.s4 = s4 }
|
|
||||||
fun setH1(h1: Long) = apply { this.h1 = h1 }
|
fun setH1(h1: Long) = apply { this.h1 = h1 }
|
||||||
fun setH2(h2: Long) = apply { this.h2 = h2 }
|
fun setH2(h2: Long) = apply { this.h2 = h2 }
|
||||||
fun setH3(h3: Long) = apply { this.h3 = h3 }
|
fun setH3(h3: Long) = apply { this.h3 = h3 }
|
||||||
fun setH4(h4: Long) = apply { this.h4 = h4 }
|
fun setH4(h4: Long) = apply { this.h4 = h4 }
|
||||||
fun setI1(i1: String) = apply { this.i1 = i1 }
|
|
||||||
fun setI2(i2: String) = apply { this.i2 = i2 }
|
|
||||||
fun setI3(i3: String) = apply { this.i3 = i3 }
|
|
||||||
fun setI4(i4: String) = apply { this.i4 = i4 }
|
|
||||||
fun setI5(i5: String) = apply { this.i5 = i5 }
|
|
||||||
fun setJ1(j1: String) = apply { this.j1 = j1 }
|
|
||||||
fun setJ2(j2: String) = apply { this.j2 = j2 }
|
|
||||||
fun setJ3(j3: String) = apply { this.j3 = j3 }
|
|
||||||
fun setItime(itime: Int) = apply { this.itime = itime }
|
|
||||||
|
|
||||||
override fun build(): WireguardConfig = configBuild().run { WireguardConfig(this@Builder) }
|
override fun build(): WireguardConfig = configBuild().run { WireguardConfig(this@Builder) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,22 +76,8 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||||
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
|
||||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
|
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks"
|
||||||
XCODE_EMBED_APP_EXTENSIONS networkextension
|
XCODE_EMBED_APP_EXTENSIONS networkextension
|
||||||
|
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||||
)
|
)
|
||||||
|
|
||||||
if(DEFINED DEPLOY)
|
|
||||||
set_target_properties(${PROJECT} PROPERTIES
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
|
||||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "distr ios.org.amnezia.AmneziaVPN"
|
|
||||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "dev ios.org.amnezia.AmneziaVPN"
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
set_target_properties(${PROJECT} PROPERTIES
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(${PROJECT} PROPERTIES
|
set_target_properties(${PROJECT} PROPERTIES
|
||||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#include "awg_configurator.h"
|
#include "awg_configurator.h"
|
||||||
#include "protocols/protocols_defs.h"
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
@ -40,20 +39,6 @@ QString AwgConfigurator::createConfig(const ServerCredentials &credentials, Dock
|
||||||
jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
|
jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
|
||||||
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
|
||||||
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
||||||
|
|
||||||
// jsonConfig[config_key::cookieReplyPacketJunkSize] = configMap.value(config_key::cookieReplyPacketJunkSize);
|
|
||||||
// jsonConfig[config_key::transportPacketJunkSize] = configMap.value(config_key::transportPacketJunkSize);
|
|
||||||
|
|
||||||
// jsonConfig[config_key::specialJunk1] = configMap.value(amnezia::config_key::specialJunk1);
|
|
||||||
// jsonConfig[config_key::specialJunk2] = configMap.value(amnezia::config_key::specialJunk2);
|
|
||||||
// jsonConfig[config_key::specialJunk3] = configMap.value(amnezia::config_key::specialJunk3);
|
|
||||||
// jsonConfig[config_key::specialJunk4] = configMap.value(amnezia::config_key::specialJunk4);
|
|
||||||
// jsonConfig[config_key::specialJunk5] = configMap.value(amnezia::config_key::specialJunk5);
|
|
||||||
// jsonConfig[config_key::controlledJunk1] = configMap.value(amnezia::config_key::controlledJunk1);
|
|
||||||
// jsonConfig[config_key::controlledJunk2] = configMap.value(amnezia::config_key::controlledJunk2);
|
|
||||||
// jsonConfig[config_key::controlledJunk3] = configMap.value(amnezia::config_key::controlledJunk3);
|
|
||||||
// jsonConfig[config_key::specialHandshakeTimeout] = configMap.value(amnezia::config_key::specialHandshakeTimeout);
|
|
||||||
|
|
||||||
jsonConfig[config_key::mtu] =
|
jsonConfig[config_key::mtu] =
|
||||||
containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().value(config_key::mtu).toString(protocols::awg::defaultMtu);
|
containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().value(config_key::mtu).toString(protocols::awg::defaultMtu);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,14 +118,15 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
|
||||||
QRegularExpression regex("redirect-gateway.*");
|
QRegularExpression regex("redirect-gateway.*");
|
||||||
config.replace(regex, "");
|
config.replace(regex, "");
|
||||||
|
|
||||||
// We don't use secondary DNS if primary DNS is AmneziaDNS
|
|
||||||
if (dns.first.contains(protocols::dns::amneziaDnsIp)) {
|
|
||||||
QRegularExpression dnsRegex("dhcp-option DNS " + dns.second);
|
|
||||||
config.replace(dnsRegex, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_settings->isSitesSplitTunnelingEnabled()) {
|
if (!m_settings->isSitesSplitTunnelingEnabled()) {
|
||||||
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
||||||
|
|
||||||
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
|
// Prevent ipv6 leak
|
||||||
|
if (NetworkUtilities::checkIpv6Enabled()) {
|
||||||
|
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
config.append("block-ipv6\n");
|
config.append("block-ipv6\n");
|
||||||
} else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
} else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
||||||
|
|
||||||
|
|
@ -134,6 +135,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
|
||||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
||||||
// Prevent ipv6 leak
|
// Prevent ipv6 leak
|
||||||
|
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||||
#endif
|
#endif
|
||||||
config.append("block-ipv6\n");
|
config.append("block-ipv6\n");
|
||||||
}
|
}
|
||||||
|
|
@ -167,15 +169,10 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(const QPair<QString
|
||||||
QRegularExpression regex("redirect-gateway.*");
|
QRegularExpression regex("redirect-gateway.*");
|
||||||
config.replace(regex, "");
|
config.replace(regex, "");
|
||||||
|
|
||||||
// We don't use secondary DNS if primary DNS is AmneziaDNS
|
|
||||||
if (dns.first.contains(protocols::dns::amneziaDnsIp)) {
|
|
||||||
QRegularExpression dnsRegex("dhcp-option DNS " + dns.second);
|
|
||||||
config.replace(dnsRegex, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
||||||
|
|
||||||
// Prevent ipv6 leak
|
// Prevent ipv6 leak
|
||||||
|
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||||
config.append("block-ipv6\n");
|
config.append("block-ipv6\n");
|
||||||
|
|
||||||
// remove block-outside-dns for all exported configs
|
// remove block-outside-dns for all exported configs
|
||||||
|
|
|
||||||
|
|
@ -140,83 +140,98 @@ QMap<DockerContainer, QString> ContainerProps::containerDetailedDescriptions()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{ DockerContainer::OpenVpn,
|
{ DockerContainer::OpenVpn,
|
||||||
QObject::tr("OpenVPN is one of the most popular and reliable VPN protocols. "
|
QObject::tr(
|
||||||
"It uses SSL/TLS encryption, supports a wide variety of devices and operating systems, "
|
"OpenVPN stands as one of the most popular and time-tested VPN protocols available.\n"
|
||||||
"and is continuously improved by the community due to its open-source nature. "
|
"It employs its unique security protocol, "
|
||||||
"It provides a good balance between speed and security but is easily recognized by DPI systems, "
|
"leveraging the strength of SSL/TLS for encryption and key exchange. "
|
||||||
"making it susceptible to blocking.\n"
|
"Furthermore, OpenVPN's support for a multitude of authentication methods makes it versatile and adaptable, "
|
||||||
"\nFeatures:\n"
|
"catering to a wide range of devices and operating systems. "
|
||||||
"* Available on all AmneziaVPN platforms\n"
|
"Due to its open-source nature, OpenVPN benefits from extensive scrutiny by the global community, "
|
||||||
"* Normal battery consumption on mobile devices\n"
|
"which continually reinforces its security. "
|
||||||
"* Flexible customization for various devices and OS\n"
|
"With a strong balance of performance, security, and compatibility, "
|
||||||
"* Operates over both TCP and UDP protocols") },
|
"OpenVPN remains a top choice for privacy-conscious individuals and businesses alike.\n\n"
|
||||||
|
"* Available in the AmneziaVPN across all platforms\n"
|
||||||
|
"* Normal power consumption on mobile devices\n"
|
||||||
|
"* Flexible customisation to suit user needs to work with different operating systems and devices\n"
|
||||||
|
"* Recognised by DPI systems and therefore susceptible to blocking\n"
|
||||||
|
"* Can operate over both TCP and UDP network protocols.") },
|
||||||
{ DockerContainer::ShadowSocks,
|
{ DockerContainer::ShadowSocks,
|
||||||
QObject::tr("Shadowsocks is based on the SOCKS5 protocol and encrypts connections using AEAD cipher. "
|
QObject::tr("Shadowsocks, inspired by the SOCKS5 protocol, safeguards the connection using the AEAD cipher. "
|
||||||
"Although designed to be discreet, it doesn't mimic a standard HTTPS connection and can be detected by some DPI systems. "
|
"Although Shadowsocks is designed to be discreet and challenging to identify, it isn't identical to a standard HTTPS connection."
|
||||||
"Due to limited support in Amnezia, we recommend using the AmneziaWG protocol.\n"
|
"However, certain traffic analysis systems might still detect a Shadowsocks connection. "
|
||||||
"\nFeatures:\n"
|
"Due to limited support in Amnezia, it's recommended to use AmneziaWG protocol.\n\n"
|
||||||
"* Available in AmneziaVPN only on desktop platforms\n"
|
"* Available in the AmneziaVPN only on desktop platforms\n"
|
||||||
"* Customizable encryption protocol\n"
|
"* Configurable encryption protocol\n"
|
||||||
"* Detectable by some DPI systems\n"
|
"* Detectable by some DPI systems\n"
|
||||||
"* Operates over TCP protocol\n") },
|
"* Works over TCP network protocol.") },
|
||||||
{ DockerContainer::Cloak,
|
{ DockerContainer::Cloak,
|
||||||
QObject::tr("This combination includes the OpenVPN protocol and the Cloak plugin, specifically designed to protect against blocking.\n"
|
QObject::tr("This is a combination of the OpenVPN protocol and the Cloak plugin designed specifically for "
|
||||||
"\nOpenVPN securely encrypts all internet traffic between your device and the server.\n"
|
"protecting against detection.\n\n"
|
||||||
"\nThe Cloak plugin further protects the connection from DPI detection. "
|
"OpenVPN provides a secure VPN connection by encrypting all internet traffic between the client "
|
||||||
"It modifies traffic metadata to disguise VPN traffic as regular web traffic and prevents detection through active probing. "
|
"and the server.\n\n"
|
||||||
"If an incoming connection fails authentication, Cloak serves a fake website, making your VPN invisible to traffic analysis systems.\n"
|
"Cloak protects OpenVPN from detection. \n\n"
|
||||||
"\nIn regions with heavy internet censorship, we strongly recommend using OpenVPN with Cloak from your first connection.\n"
|
"Cloak can modify packet metadata so that it completely masks VPN traffic as normal web traffic, "
|
||||||
"\nFeatures:\n"
|
"and also protects the VPN from detection by Active Probing. This makes it very resistant to "
|
||||||
"* Available on all AmneziaVPN platforms\n"
|
"being detected\n\n"
|
||||||
|
"Immediately after receiving the first data packet, Cloak authenticates the incoming connection. "
|
||||||
|
"If authentication fails, the plugin masks the server as a fake website and your VPN becomes "
|
||||||
|
"invisible to analysis systems.\n\n"
|
||||||
|
"* Available in the AmneziaVPN across all platforms\n"
|
||||||
"* High power consumption on mobile devices\n"
|
"* High power consumption on mobile devices\n"
|
||||||
"* Flexible configuration options\n"
|
"* Flexible settings\n"
|
||||||
"* Undetectable by DPI systems\n"
|
"* Not recognised by detection systems\n"
|
||||||
"* Operates over TCP protocol on port 443") },
|
"* Works over TCP network protocol, 443 port.\n") },
|
||||||
{ DockerContainer::WireGuard,
|
{ DockerContainer::WireGuard,
|
||||||
QObject::tr("WireGuard is a modern, streamlined VPN protocol offering stable connectivity and excellent performance across all devices. "
|
QObject::tr("A relatively new popular VPN protocol with a simplified architecture.\n"
|
||||||
"It uses fixed encryption settings, delivering lower latency and higher data transfer speeds compared to OpenVPN. "
|
"WireGuard provides stable VPN connection and high performance on all devices. It uses hard-coded encryption "
|
||||||
"However, WireGuard is easily identifiable by DPI systems due to its distinctive packet signatures, making it susceptible to blocking.\n"
|
"settings. WireGuard compared to OpenVPN has lower latency and better data transfer throughput.\n"
|
||||||
"\nFeatures:\n"
|
"WireGuard is very susceptible to detection and blocking due to its distinct packet signatures. "
|
||||||
"* Available on all AmneziaVPN platforms\n"
|
"Unlike some other VPN protocols that employ obfuscation techniques, "
|
||||||
"* Low power consumption on mobile devices\n"
|
"the consistent signature patterns of WireGuard packets can be more easily identified and "
|
||||||
"* Minimal configuration required\n"
|
"thus blocked by advanced Deep Packet Inspection (DPI) systems and other network monitoring tools.\n\n"
|
||||||
"* Easily detected by DPI systems (susceptible to blocking)\n"
|
"* Available in the AmneziaVPN across all platforms\n"
|
||||||
"* Operates over UDP protocol") },
|
"* Low power consumption\n"
|
||||||
|
"* Minimum number of settings\n"
|
||||||
|
"* Easily recognised by DPI analysis systems, susceptible to blocking\n"
|
||||||
|
"* Works over UDP network protocol.") },
|
||||||
{ DockerContainer::Awg,
|
{ DockerContainer::Awg,
|
||||||
QObject::tr("AmneziaWG is a modern VPN protocol based on WireGuard, "
|
QObject::tr("A modern iteration of the popular VPN protocol, "
|
||||||
"combining simplified architecture with high performance across all devices. "
|
"AmneziaWG builds upon the foundation set by WireGuard, "
|
||||||
"It addresses WireGuard's main vulnerability (easy detection by DPI systems) through advanced obfuscation techniques, "
|
"retaining its simplified architecture and high-performance capabilities across devices.\n"
|
||||||
"making VPN traffic indistinguishable from regular internet traffic.\n"
|
"While WireGuard is known for its efficiency, "
|
||||||
"\nAmneziaWG is an excellent choice for those seeking a fast, stealthy VPN connection.\n"
|
"it had issues with being easily detected due to its distinct packet signatures. "
|
||||||
"\nFeatures:\n"
|
"AmneziaWG solves this problem by using better obfuscation methods, "
|
||||||
"* Available on all AmneziaVPN platforms\n"
|
"making its traffic blend in with regular internet traffic.\n"
|
||||||
"* Low battery consumption on mobile devices\n"
|
"This means that AmneziaWG keeps the fast performance of the original "
|
||||||
"* Minimal settings required\n"
|
"while adding an extra layer of stealth, "
|
||||||
"* Undetectable by traffic analysis systems (DPI)\n"
|
"making it a great choice for those wanting a fast and discreet VPN connection.\n\n"
|
||||||
"* Operates over UDP protocol") },
|
"* Available in the AmneziaVPN across all platforms\n"
|
||||||
|
"* Low power consumption\n"
|
||||||
|
"* Minimum number of settings\n"
|
||||||
|
"* Not recognised by traffic analysis systems\n"
|
||||||
|
"* Works over UDP network protocol.") },
|
||||||
{ DockerContainer::Xray,
|
{ DockerContainer::Xray,
|
||||||
QObject::tr("REALITY is an innovative protocol developed by the creators of XRay, designed specifically to combat high levels of internet censorship. "
|
QObject::tr("The REALITY protocol, a pioneering development by the creators of XRay, "
|
||||||
"REALITY identifies censorship systems during the TLS handshake, "
|
"is designed to provide the highest level of protection against detection through its innovative approach to security and privacy.\n"
|
||||||
"redirecting suspicious traffic seamlessly to legitimate websites like google.com while providing genuine TLS certificates. "
|
"It uniquely identifies attackers during the TLS handshake phase, seamlessly operating as a proxy for legitimate clients while diverting attackers to genuine websites, "
|
||||||
"This allows VPN traffic to blend indistinguishably with regular web traffic without special configuration."
|
"thus presenting an authentic TLS certificate and data. \n"
|
||||||
"\nUnlike older protocols such as VMess, VLESS, and XTLS-Vision, REALITY incorporates an advanced built-in \"friend-or-foe\" detection mechanism, "
|
"This advanced capability differentiates REALITY from similar technologies by its ability to disguise web traffic as coming from random, "
|
||||||
"effectively protecting against DPI and other traffic analysis methods.\n"
|
"legitimate sites without the need for specific configurations. \n"
|
||||||
"\nFeatures:\n"
|
"Unlike older protocols such as VMess, VLESS, and the XTLS-Vision transport, "
|
||||||
"* Resistant to active probing and DPI detection\n"
|
"REALITY's innovative \"friend or foe\" recognition at the TLS handshake enhances security. "
|
||||||
"* No special configuration required to disguise traffic\n"
|
"This makes REALITY a robust solution for maintaining internet freedom.")
|
||||||
"* Highly effective in heavily censored regions\n"
|
},
|
||||||
"* Minimal battery consumption on devices\n"
|
|
||||||
"* Operates over TCP protocol") },
|
|
||||||
{ DockerContainer::Ipsec,
|
{ DockerContainer::Ipsec,
|
||||||
QObject::tr("IKEv2, combined with IPSec encryption, is a modern and reliable VPN protocol. "
|
QObject::tr("IKEv2, paired with the IPSec encryption layer, stands as a modern and stable VPN protocol.\n"
|
||||||
"It reconnects quickly when switching networks or devices, making it ideal for dynamic network environments. "
|
"One of its distinguishing features is its ability to swiftly switch between networks and devices, "
|
||||||
"While it provides good security and speed, it's easily recognized by DPI systems and susceptible to blocking.\n"
|
"making it particularly adaptive in dynamic network environments. \n"
|
||||||
"\nFeatures:\n"
|
"While it offers a blend of security, stability, and speed, "
|
||||||
"* Available in AmneziaVPN only on Windows\n"
|
"it's essential to note that IKEv2 can be easily detected and is susceptible to blocking.\n\n"
|
||||||
"* Low battery consumption on mobile devices\n"
|
"* Available in the AmneziaVPN only on Windows\n"
|
||||||
"* Minimal configuration required\n"
|
"* Low power consumption, on mobile devices\n"
|
||||||
"* Detectable by DPI analysis systems(easily blocked)\n"
|
"* Minimal configuration\n"
|
||||||
"* Operates over UDP protocol(ports 500 and 4500)") },
|
"* Recognised by DPI analysis systems\n"
|
||||||
|
"* Works over UDP network protocol, ports 500 and 4500.") },
|
||||||
|
|
||||||
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
||||||
{ DockerContainer::Dns, QObject::tr("DNS Service") },
|
{ DockerContainer::Dns, QObject::tr("DNS Service") },
|
||||||
|
|
|
||||||
|
|
@ -22,21 +22,12 @@ namespace apiDefs
|
||||||
namespace key
|
namespace key
|
||||||
{
|
{
|
||||||
constexpr QLatin1String configVersion("config_version");
|
constexpr QLatin1String configVersion("config_version");
|
||||||
constexpr QLatin1String apiEndpoint("api_endpoint");
|
|
||||||
constexpr QLatin1String apiKey("api_key");
|
|
||||||
constexpr QLatin1String description("description");
|
|
||||||
constexpr QLatin1String name("name");
|
|
||||||
constexpr QLatin1String protocol("protocol");
|
|
||||||
|
|
||||||
constexpr QLatin1String apiConfig("api_config");
|
constexpr QLatin1String apiConfig("api_config");
|
||||||
constexpr QLatin1String stackType("stack_type");
|
constexpr QLatin1String stackType("stack_type");
|
||||||
constexpr QLatin1String serviceType("service_type");
|
constexpr QLatin1String serviceType("service_type");
|
||||||
constexpr QLatin1String cliVersion("cli_version");
|
|
||||||
constexpr QLatin1String supportedProtocols("supported_protocols");
|
|
||||||
|
|
||||||
constexpr QLatin1String vpnKey("vpn_key");
|
constexpr QLatin1String vpnKey("vpn_key");
|
||||||
constexpr QLatin1String config("config");
|
|
||||||
constexpr QLatin1String configs("configs");
|
|
||||||
|
|
||||||
constexpr QLatin1String installationUuid("installation_uuid");
|
constexpr QLatin1String installationUuid("installation_uuid");
|
||||||
constexpr QLatin1String workerLastUpdated("worker_last_updated");
|
constexpr QLatin1String workerLastUpdated("worker_last_updated");
|
||||||
|
|
@ -60,10 +51,6 @@ namespace apiDefs
|
||||||
constexpr QLatin1String website("website");
|
constexpr QLatin1String website("website");
|
||||||
constexpr QLatin1String websiteName("website_name");
|
constexpr QLatin1String websiteName("website_name");
|
||||||
constexpr QLatin1String telegram("telegram");
|
constexpr QLatin1String telegram("telegram");
|
||||||
|
|
||||||
constexpr QLatin1String id("id");
|
|
||||||
constexpr QLatin1String orderId("order_id");
|
|
||||||
constexpr QLatin1String migrationCode("migration_code");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
const int requestTimeoutMsecs = 12 * 1000; // 12 secs
|
||||||
|
|
|
||||||
|
|
@ -3,24 +3,6 @@
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const QByteArray AMNEZIA_CONFIG_SIGNATURE = QByteArray::fromHex("000000ff");
|
|
||||||
|
|
||||||
QString escapeUnicode(const QString &input)
|
|
||||||
{
|
|
||||||
QString output;
|
|
||||||
for (QChar c : input) {
|
|
||||||
if (c.unicode() < 0x20 || c.unicode() > 0x7E) {
|
|
||||||
output += QString("\\u%1").arg(QString::number(c.unicode(), 16).rightJustified(4, '0'));
|
|
||||||
} else {
|
|
||||||
output += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool apiUtils::isSubscriptionExpired(const QString &subscriptionEndDate)
|
bool apiUtils::isSubscriptionExpired(const QString &subscriptionEndDate)
|
||||||
{
|
{
|
||||||
QDateTime now = QDateTime::currentDateTime();
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
|
@ -41,21 +23,13 @@ bool apiUtils::isServerFromApi(const QJsonObject &serverConfigObject)
|
||||||
apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObject)
|
apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObject)
|
||||||
{
|
{
|
||||||
auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt();
|
auto configVersion = serverConfigObject.value(apiDefs::key::configVersion).toInt();
|
||||||
|
|
||||||
switch (configVersion) {
|
switch (configVersion) {
|
||||||
case apiDefs::ConfigSource::Telegram: {
|
case apiDefs::ConfigSource::Telegram: {
|
||||||
constexpr QLatin1String freeV2Endpoint(FREE_V2_ENDPOINT);
|
|
||||||
constexpr QLatin1String premiumV1Endpoint(PREM_V1_ENDPOINT);
|
|
||||||
|
|
||||||
auto apiEndpoint = serverConfigObject.value(apiDefs::key::apiEndpoint).toString();
|
|
||||||
|
|
||||||
if (apiEndpoint.contains(premiumV1Endpoint)) {
|
|
||||||
return apiDefs::ConfigType::AmneziaPremiumV1;
|
|
||||||
} else if (apiEndpoint.contains(freeV2Endpoint)) {
|
|
||||||
return apiDefs::ConfigType::AmneziaFreeV2;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
case apiDefs::ConfigSource::AmneziaGateway: {
|
case apiDefs::ConfigSource::AmneziaGateway: {
|
||||||
|
constexpr QLatin1String stackPremium("prem");
|
||||||
|
constexpr QLatin1String stackFree("free");
|
||||||
|
|
||||||
constexpr QLatin1String servicePremium("amnezia-premium");
|
constexpr QLatin1String servicePremium("amnezia-premium");
|
||||||
constexpr QLatin1String serviceFree("amnezia-free");
|
constexpr QLatin1String serviceFree("amnezia-free");
|
||||||
constexpr QLatin1String serviceExternalPremium("external-premium");
|
constexpr QLatin1String serviceExternalPremium("external-premium");
|
||||||
|
|
@ -96,9 +70,6 @@ amnezia::ErrorCode apiUtils::checkNetworkReplyErrors(const QList<QSslError> &ssl
|
||||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
||||||
qDebug() << reply->error();
|
qDebug() << reply->error();
|
||||||
return amnezia::ErrorCode::ApiConfigTimeoutError;
|
return amnezia::ErrorCode::ApiConfigTimeoutError;
|
||||||
} else if (reply->error() == QNetworkReply::NetworkError::OperationNotImplementedError) {
|
|
||||||
qDebug() << reply->error();
|
|
||||||
return amnezia::ErrorCode::ApiUpdateRequestError;
|
|
||||||
} else {
|
} else {
|
||||||
QString err = reply->errorString();
|
QString err = reply->errorString();
|
||||||
int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
|
|
@ -124,41 +95,3 @@ bool apiUtils::isPremiumServer(const QJsonObject &serverConfigObject)
|
||||||
apiDefs::ConfigType::ExternalPremium };
|
apiDefs::ConfigType::ExternalPremium };
|
||||||
return premiumTypes.contains(getConfigType(serverConfigObject));
|
return premiumTypes.contains(getConfigType(serverConfigObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString apiUtils::getPremiumV1VpnKey(const QJsonObject &serverConfigObject)
|
|
||||||
{
|
|
||||||
if (apiUtils::getConfigType(serverConfigObject) != apiDefs::ConfigType::AmneziaPremiumV1) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QPair<QString, QVariant>> orderedFields;
|
|
||||||
orderedFields.append(qMakePair(apiDefs::key::name, serverConfigObject[apiDefs::key::name].toString()));
|
|
||||||
orderedFields.append(qMakePair(apiDefs::key::description, serverConfigObject[apiDefs::key::description].toString()));
|
|
||||||
orderedFields.append(qMakePair(apiDefs::key::configVersion, serverConfigObject[apiDefs::key::configVersion].toDouble()));
|
|
||||||
orderedFields.append(qMakePair(apiDefs::key::protocol, serverConfigObject[apiDefs::key::protocol].toString()));
|
|
||||||
orderedFields.append(qMakePair(apiDefs::key::apiEndpoint, serverConfigObject[apiDefs::key::apiEndpoint].toString()));
|
|
||||||
orderedFields.append(qMakePair(apiDefs::key::apiKey, serverConfigObject[apiDefs::key::apiKey].toString()));
|
|
||||||
|
|
||||||
QString vpnKeyStr = "{";
|
|
||||||
for (int i = 0; i < orderedFields.size(); ++i) {
|
|
||||||
const auto &pair = orderedFields[i];
|
|
||||||
if (pair.second.typeId() == QMetaType::Type::QString) {
|
|
||||||
vpnKeyStr += "\"" + pair.first + "\": \"" + pair.second.toString() + "\"";
|
|
||||||
} else if (pair.second.typeId() == QMetaType::Type::Double || pair.second.typeId() == QMetaType::Type::Int) {
|
|
||||||
vpnKeyStr += "\"" + pair.first + "\": " + QString::number(pair.second.toDouble(), 'f', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < orderedFields.size() - 1) {
|
|
||||||
vpnKeyStr += ", ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vpnKeyStr += "}";
|
|
||||||
|
|
||||||
QByteArray vpnKeyCompressed = escapeUnicode(vpnKeyStr).toUtf8();
|
|
||||||
vpnKeyCompressed = qCompress(vpnKeyCompressed, 6);
|
|
||||||
vpnKeyCompressed = vpnKeyCompressed.mid(4);
|
|
||||||
|
|
||||||
QByteArray signedData = AMNEZIA_CONFIG_SIGNATURE + vpnKeyCompressed;
|
|
||||||
|
|
||||||
return QString("vpn://%1").arg(QString(signedData.toBase64(QByteArray::Base64UrlEncoding)));
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@ namespace apiUtils
|
||||||
apiDefs::ConfigSource getConfigSource(const QJsonObject &serverConfigObject);
|
apiDefs::ConfigSource getConfigSource(const QJsonObject &serverConfigObject);
|
||||||
|
|
||||||
amnezia::ErrorCode checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply);
|
amnezia::ErrorCode checkNetworkReplyErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply);
|
||||||
|
|
||||||
QString getPremiumV1VpnKey(const QJsonObject &serverConfigObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // APIUTILS_H
|
#endif // APIUTILS_H
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,6 @@ void CoreController::initModels()
|
||||||
m_sitesModel.reset(new SitesModel(m_settings, this));
|
m_sitesModel.reset(new SitesModel(m_settings, this));
|
||||||
m_engine->rootContext()->setContextProperty("SitesModel", m_sitesModel.get());
|
m_engine->rootContext()->setContextProperty("SitesModel", m_sitesModel.get());
|
||||||
|
|
||||||
m_allowedDnsModel.reset(new AllowedDnsModel(m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("AllowedDnsModel", m_allowedDnsModel.get());
|
|
||||||
|
|
||||||
m_appSplitTunnelingModel.reset(new AppSplitTunnelingModel(m_settings, this));
|
m_appSplitTunnelingModel.reset(new AppSplitTunnelingModel(m_settings, this));
|
||||||
m_engine->rootContext()->setContextProperty("AppSplitTunnelingModel", m_appSplitTunnelingModel.get());
|
m_engine->rootContext()->setContextProperty("AppSplitTunnelingModel", m_appSplitTunnelingModel.get());
|
||||||
|
|
||||||
|
|
@ -133,9 +130,6 @@ void CoreController::initControllers()
|
||||||
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
||||||
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
|
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
|
||||||
|
|
||||||
m_allowedDnsController.reset(new AllowedDnsController(m_settings, m_allowedDnsModel));
|
|
||||||
m_engine->rootContext()->setContextProperty("AllowedDnsController", m_allowedDnsController.get());
|
|
||||||
|
|
||||||
m_appSplitTunnelingController.reset(new AppSplitTunnelingController(m_settings, m_appSplitTunnelingModel));
|
m_appSplitTunnelingController.reset(new AppSplitTunnelingController(m_settings, m_appSplitTunnelingModel));
|
||||||
m_engine->rootContext()->setContextProperty("AppSplitTunnelingController", m_appSplitTunnelingController.get());
|
m_engine->rootContext()->setContextProperty("AppSplitTunnelingController", m_appSplitTunnelingController.get());
|
||||||
|
|
||||||
|
|
@ -148,9 +142,6 @@ void CoreController::initControllers()
|
||||||
|
|
||||||
m_apiConfigsController.reset(new ApiConfigsController(m_serversModel, m_apiServicesModel, m_settings));
|
m_apiConfigsController.reset(new ApiConfigsController(m_serversModel, m_apiServicesModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("ApiConfigsController", m_apiConfigsController.get());
|
m_engine->rootContext()->setContextProperty("ApiConfigsController", m_apiConfigsController.get());
|
||||||
|
|
||||||
m_apiPremV1MigrationController.reset(new ApiPremV1MigrationController(m_serversModel, m_settings, this));
|
|
||||||
m_engine->rootContext()->setContextProperty("ApiPremV1MigrationController", m_apiPremV1MigrationController.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreController::initAndroidController()
|
void CoreController::initAndroidController()
|
||||||
|
|
@ -223,9 +214,6 @@ void CoreController::initSignalHandlers()
|
||||||
initAutoConnectHandler();
|
initAutoConnectHandler();
|
||||||
initAmneziaDnsToggledHandler();
|
initAmneziaDnsToggledHandler();
|
||||||
initPrepareConfigHandler();
|
initPrepareConfigHandler();
|
||||||
initImportPremiumV2VpnKeyHandler();
|
|
||||||
initShowMigrationDrawerHandler();
|
|
||||||
initStrictKillSwitchHandler();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreController::initNotificationHandler()
|
void CoreController::initNotificationHandler()
|
||||||
|
|
@ -368,31 +356,6 @@ void CoreController::initPrepareConfigHandler()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreController::initImportPremiumV2VpnKeyHandler()
|
|
||||||
{
|
|
||||||
connect(m_apiPremV1MigrationController.get(), &ApiPremV1MigrationController::importPremiumV2VpnKey, this, [this](const QString &vpnKey) {
|
|
||||||
m_importController->extractConfigFromData(vpnKey);
|
|
||||||
m_importController->importConfig();
|
|
||||||
|
|
||||||
emit m_apiPremV1MigrationController->migrationFinished();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoreController::initShowMigrationDrawerHandler()
|
|
||||||
{
|
|
||||||
QTimer::singleShot(1000, this, [this]() {
|
|
||||||
if (m_apiPremV1MigrationController->isPremV1MigrationReminderActive() && m_apiPremV1MigrationController->hasConfigsToMigration()) {
|
|
||||||
m_apiPremV1MigrationController->showMigrationDrawer();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoreController::initStrictKillSwitchHandler()
|
|
||||||
{
|
|
||||||
connect(m_settingsController.get(), &SettingsController::strictKillSwitchEnabledChanged, m_vpnConnection.get(),
|
|
||||||
&VpnConnection::onKillSwitchModeChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedPointer<PageController> CoreController::pageController() const
|
QSharedPointer<PageController> CoreController::pageController() const
|
||||||
{
|
{
|
||||||
return m_pageController;
|
return m_pageController;
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
#include "ui/controllers/api/apiConfigsController.h"
|
#include "ui/controllers/api/apiConfigsController.h"
|
||||||
#include "ui/controllers/api/apiSettingsController.h"
|
#include "ui/controllers/api/apiSettingsController.h"
|
||||||
#include "ui/controllers/api/apiPremV1MigrationController.h"
|
|
||||||
#include "ui/controllers/appSplitTunnelingController.h"
|
#include "ui/controllers/appSplitTunnelingController.h"
|
||||||
#include "ui/controllers/allowedDnsController.h"
|
|
||||||
#include "ui/controllers/connectionController.h"
|
#include "ui/controllers/connectionController.h"
|
||||||
#include "ui/controllers/exportController.h"
|
#include "ui/controllers/exportController.h"
|
||||||
#include "ui/controllers/focusController.h"
|
#include "ui/controllers/focusController.h"
|
||||||
|
|
@ -20,7 +18,6 @@
|
||||||
#include "ui/controllers/sitesController.h"
|
#include "ui/controllers/sitesController.h"
|
||||||
#include "ui/controllers/systemController.h"
|
#include "ui/controllers/systemController.h"
|
||||||
|
|
||||||
#include "ui/models/allowed_dns_model.h"
|
|
||||||
#include "ui/models/containers_model.h"
|
#include "ui/models/containers_model.h"
|
||||||
#include "ui/models/languageModel.h"
|
#include "ui/models/languageModel.h"
|
||||||
#include "ui/models/protocols/cloakConfigModel.h"
|
#include "ui/models/protocols/cloakConfigModel.h"
|
||||||
|
|
@ -83,9 +80,6 @@ private:
|
||||||
void initAutoConnectHandler();
|
void initAutoConnectHandler();
|
||||||
void initAmneziaDnsToggledHandler();
|
void initAmneziaDnsToggledHandler();
|
||||||
void initPrepareConfigHandler();
|
void initPrepareConfigHandler();
|
||||||
void initImportPremiumV2VpnKeyHandler();
|
|
||||||
void initShowMigrationDrawerHandler();
|
|
||||||
void initStrictKillSwitchHandler();
|
|
||||||
|
|
||||||
QQmlApplicationEngine *m_engine {}; // TODO use parent child system here?
|
QQmlApplicationEngine *m_engine {}; // TODO use parent child system here?
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
@ -108,11 +102,9 @@ private:
|
||||||
QScopedPointer<SitesController> m_sitesController;
|
QScopedPointer<SitesController> m_sitesController;
|
||||||
QScopedPointer<SystemController> m_systemController;
|
QScopedPointer<SystemController> m_systemController;
|
||||||
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
||||||
QScopedPointer<AllowedDnsController> m_allowedDnsController;
|
|
||||||
|
|
||||||
QScopedPointer<ApiSettingsController> m_apiSettingsController;
|
QScopedPointer<ApiSettingsController> m_apiSettingsController;
|
||||||
QScopedPointer<ApiConfigsController> m_apiConfigsController;
|
QScopedPointer<ApiConfigsController> m_apiConfigsController;
|
||||||
QScopedPointer<ApiPremV1MigrationController> m_apiPremV1MigrationController;
|
|
||||||
|
|
||||||
QSharedPointer<ContainersModel> m_containersModel;
|
QSharedPointer<ContainersModel> m_containersModel;
|
||||||
QSharedPointer<ContainersModel> m_defaultServerContainersModel;
|
QSharedPointer<ContainersModel> m_defaultServerContainersModel;
|
||||||
|
|
@ -120,7 +112,6 @@ private:
|
||||||
QSharedPointer<LanguageModel> m_languageModel;
|
QSharedPointer<LanguageModel> m_languageModel;
|
||||||
QSharedPointer<ProtocolsModel> m_protocolsModel;
|
QSharedPointer<ProtocolsModel> m_protocolsModel;
|
||||||
QSharedPointer<SitesModel> m_sitesModel;
|
QSharedPointer<SitesModel> m_sitesModel;
|
||||||
QSharedPointer<AllowedDnsModel> m_allowedDnsModel;
|
|
||||||
QSharedPointer<AppSplitTunnelingModel> m_appSplitTunnelingModel;
|
QSharedPointer<AppSplitTunnelingModel> m_appSplitTunnelingModel;
|
||||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,20 +7,14 @@
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
#include "QBlockCipher.h"
|
#include "QBlockCipher.h"
|
||||||
#include "QRsa.h"
|
#include "QRsa.h"
|
||||||
|
|
||||||
#include "amnezia_application.h"
|
#include "amnezia_application.h"
|
||||||
#include "core/api/apiUtils.h"
|
#include "core/api/apiUtils.h"
|
||||||
#include "core/networkUtilities.h"
|
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
|
||||||
#include "core/ipcclient.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
namespace configKey
|
namespace configKey
|
||||||
|
|
@ -36,17 +30,10 @@ namespace
|
||||||
constexpr QLatin1String errorResponsePattern1("No active configuration found for");
|
constexpr QLatin1String errorResponsePattern1("No active configuration found for");
|
||||||
constexpr QLatin1String errorResponsePattern2("No non-revoked public key found for");
|
constexpr QLatin1String errorResponsePattern2("No non-revoked public key found for");
|
||||||
constexpr QLatin1String errorResponsePattern3("Account not found.");
|
constexpr QLatin1String errorResponsePattern3("Account not found.");
|
||||||
|
|
||||||
constexpr QLatin1String updateRequestResponsePattern("client version update is required");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GatewayController::GatewayController(const QString &gatewayEndpoint, const bool isDevEnvironment, const int requestTimeoutMsecs,
|
GatewayController::GatewayController(const QString &gatewayEndpoint, bool isDevEnvironment, int requestTimeoutMsecs, QObject *parent)
|
||||||
const bool isStrictKillSwitchEnabled, QObject *parent)
|
: QObject(parent), m_gatewayEndpoint(gatewayEndpoint), m_isDevEnvironment(isDevEnvironment), m_requestTimeoutMsecs(requestTimeoutMsecs)
|
||||||
: QObject(parent),
|
|
||||||
m_gatewayEndpoint(gatewayEndpoint),
|
|
||||||
m_isDevEnvironment(isDevEnvironment),
|
|
||||||
m_requestTimeoutMsecs(requestTimeoutMsecs),
|
|
||||||
m_isStrictKillSwitchEnabled(isStrictKillSwitchEnabled)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,17 +50,6 @@ ErrorCode GatewayController::get(const QString &endpoint, QByteArray &responseBo
|
||||||
|
|
||||||
request.setUrl(QString(endpoint).arg(m_gatewayEndpoint));
|
request.setUrl(QString(endpoint).arg(m_gatewayEndpoint));
|
||||||
|
|
||||||
// bypass killSwitch exceptions for API-gateway
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
|
||||||
if (m_isStrictKillSwitchEnabled) {
|
|
||||||
QString host = QUrl(request.url()).host();
|
|
||||||
QString ip = NetworkUtilities::getIPAddress(host);
|
|
||||||
if (!ip.isEmpty()) {
|
|
||||||
IpcClient::Interface()->addKillSwitchAllowedRange(QStringList { ip });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QNetworkReply *reply;
|
QNetworkReply *reply;
|
||||||
reply = amnApp->networkManager()->get(request);
|
reply = amnApp->networkManager()->get(request);
|
||||||
|
|
||||||
|
|
@ -125,17 +101,6 @@ ErrorCode GatewayController::post(const QString &endpoint, const QJsonObject api
|
||||||
|
|
||||||
request.setUrl(endpoint.arg(m_gatewayEndpoint));
|
request.setUrl(endpoint.arg(m_gatewayEndpoint));
|
||||||
|
|
||||||
// bypass killSwitch exceptions for API-gateway
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
|
||||||
if (m_isStrictKillSwitchEnabled) {
|
|
||||||
QString host = QUrl(request.url()).host();
|
|
||||||
QString ip = NetworkUtilities::getIPAddress(host);
|
|
||||||
if (!ip.isEmpty()) {
|
|
||||||
IpcClient::Interface()->addKillSwitchAllowedRange(QStringList { ip });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QSimpleCrypto::QBlockCipher blockCipher;
|
QSimpleCrypto::QBlockCipher blockCipher;
|
||||||
QByteArray key = blockCipher.generatePrivateSalt(32);
|
QByteArray key = blockCipher.generatePrivateSalt(32);
|
||||||
QByteArray iv = blockCipher.generatePrivateSalt(32);
|
QByteArray iv = blockCipher.generatePrivateSalt(32);
|
||||||
|
|
@ -313,13 +278,6 @@ bool GatewayController::shouldBypassProxy(QNetworkReply *reply, const QByteArray
|
||||||
qDebug() << reply->error();
|
qDebug() << reply->error();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (reply->error() == QNetworkReply::NetworkError::OperationNotImplementedError) {
|
|
||||||
if (responseBody.contains(updateRequestResponsePattern)) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
qDebug() << reply->error();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
} else if (reply->error() != QNetworkReply::NetworkError::NoError) {
|
||||||
qDebug() << reply->error();
|
qDebug() << reply->error();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,7 @@ class GatewayController : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GatewayController(const QString &gatewayEndpoint, const bool isDevEnvironment, const int requestTimeoutMsecs,
|
explicit GatewayController(const QString &gatewayEndpoint, bool isDevEnvironment, int requestTimeoutMsecs, QObject *parent = nullptr);
|
||||||
const bool isStrictKillSwitchEnabled, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
amnezia::ErrorCode get(const QString &endpoint, QByteArray &responseBody);
|
amnezia::ErrorCode get(const QString &endpoint, QByteArray &responseBody);
|
||||||
amnezia::ErrorCode post(const QString &endpoint, const QJsonObject apiPayload, QByteArray &responseBody);
|
amnezia::ErrorCode post(const QString &endpoint, const QJsonObject apiPayload, QByteArray &responseBody);
|
||||||
|
|
@ -31,7 +30,6 @@ private:
|
||||||
int m_requestTimeoutMsecs;
|
int m_requestTimeoutMsecs;
|
||||||
QString m_gatewayEndpoint;
|
QString m_gatewayEndpoint;
|
||||||
bool m_isDevEnvironment = false;
|
bool m_isDevEnvironment = false;
|
||||||
bool m_isStrictKillSwitchEnabled = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GATEWAYCONTROLLER_H
|
#endif // GATEWAYCONTROLLER_H
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
||||||
|
|
||||||
if (overwriteMode == libssh::ScpOverwriteMode::ScpOverwriteExisting) {
|
if (overwriteMode == libssh::ScpOverwriteMode::ScpOverwriteExisting) {
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, path),
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
cbReadStd, cbReadStd);
|
cbReadStd, cbReadStd);
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
||||||
return e;
|
return e;
|
||||||
} else if (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting) {
|
} else if (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting) {
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QStringLiteral("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName, tmpFileName),
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(tmpFileName),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
cbReadStd, cbReadStd);
|
cbReadStd, cbReadStd);
|
||||||
|
|
||||||
|
|
@ -154,7 +154,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QStringLiteral("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName, path),
|
replaceVars(QString("sudo docker exec -i $CONTAINER_NAME sh -c \"cat %1 >> %2\"").arg(tmpFileName).arg(path),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
cbReadStd, cbReadStd);
|
cbReadStd, cbReadStd);
|
||||||
|
|
||||||
|
|
@ -177,7 +177,7 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
|
||||||
|
|
||||||
errorCode = ErrorCode::NoError;
|
errorCode = ErrorCode::NoError;
|
||||||
|
|
||||||
QString script = QStringLiteral("sudo docker exec -i %1 sh -c \"xxd -p '%2'\"").arg(ContainerProps::containerToString(container), path);
|
QString script = QString("sudo docker exec -i %1 sh -c \"xxd -p \'%2\'\"").arg(ContainerProps::containerToString(container)).arg(path);
|
||||||
|
|
||||||
QString stdOut;
|
QString stdOut;
|
||||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||||
|
|
@ -349,7 +349,7 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
||||||
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
|
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
|
||||||
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|
||||||
|| (oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
|
|| (oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)
|
||||||
!= newProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort))
|
!= newProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort))
|
||||||
|| (oldProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount)
|
|| (oldProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount)
|
||||||
!= newProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount))
|
!= newProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount))
|
||||||
|| (oldProtoConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize)
|
|| (oldProtoConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize)
|
||||||
|
|
@ -366,13 +366,8 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
||||||
!= newProtoConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader))
|
!= newProtoConfig.value(config_key::responsePacketMagicHeader).toString(protocols::awg::defaultResponsePacketMagicHeader))
|
||||||
|| (oldProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader)
|
|| (oldProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader)
|
||||||
!= newProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader))
|
!= newProtoConfig.value(config_key::underloadPacketMagicHeader).toString(protocols::awg::defaultUnderloadPacketMagicHeader))
|
||||||
|| (oldProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader))
|
|| (oldProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader)
|
||||||
!= newProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader))
|
!= newProtoConfig.value(config_key::transportPacketMagicHeader).toString(protocols::awg::defaultTransportPacketMagicHeader)))
|
||||||
// || (oldProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize)
|
|
||||||
// != newProtoConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize))
|
|
||||||
// || (oldProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize)
|
|
||||||
// != newProtoConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize))
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -380,7 +375,7 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
||||||
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
|
if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)
|
||||||
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|
!= newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress))
|
||||||
|| (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
|
|| (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)
|
||||||
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)))
|
!= newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,13 +383,6 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == DockerContainer::Xray) {
|
|
||||||
if (oldProtoConfig.value(config_key::port).toString(protocols::xray::defaultPort)
|
|
||||||
!= newProtoConfig.value(config_key::port).toString(protocols::xray::defaultPort)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,13 +448,11 @@ ErrorCode ServerController::buildContainerWorker(const ServerCredentials &creden
|
||||||
runScript(credentials,
|
runScript(credentials,
|
||||||
replaceVars(amnezia::scriptData(SharedScriptType::build_container), genVarsForScript(credentials, container, config)),
|
replaceVars(amnezia::scriptData(SharedScriptType::build_container), genVarsForScript(credentials, container, config)),
|
||||||
cbReadStdOut, cbReadStdErr);
|
cbReadStdOut, cbReadStdErr);
|
||||||
|
|
||||||
if (stdOut.contains("doesn't work on cgroups v2"))
|
if (stdOut.contains("doesn't work on cgroups v2"))
|
||||||
return ErrorCode::ServerDockerOnCgroupsV2;
|
return ErrorCode::ServerDockerOnCgroupsV2;
|
||||||
if (stdOut.contains("cgroup mountpoint does not exist"))
|
if (stdOut.contains("cgroup mountpoint does not exist"))
|
||||||
return ErrorCode::ServerCgroupMountpoint;
|
return ErrorCode::ServerCgroupMountpoint;
|
||||||
if (stdOut.contains("have reached") && stdOut.contains("pull rate limit"))
|
|
||||||
return ErrorCode::DockerPullRateLimit;
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
@ -646,9 +632,6 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
||||||
vars.append({ { "$UNDERLOAD_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::underloadPacketMagicHeader).toString() } });
|
vars.append({ { "$UNDERLOAD_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::underloadPacketMagicHeader).toString() } });
|
||||||
vars.append({ { "$TRANSPORT_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::transportPacketMagicHeader).toString() } });
|
vars.append({ { "$TRANSPORT_PACKET_MAGIC_HEADER", amneziaWireguarConfig.value(config_key::transportPacketMagicHeader).toString() } });
|
||||||
|
|
||||||
vars.append({ { "$COOKIE_REPLY_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::cookieReplyPacketJunkSize).toString() } });
|
|
||||||
vars.append({ { "$TRANSPORT_PACKET_JUNK_SIZE", amneziaWireguarConfig.value(config_key::transportPacketJunkSize).toString() } });
|
|
||||||
|
|
||||||
// Socks5 proxy vars
|
// Socks5 proxy vars
|
||||||
vars.append({ { "$SOCKS5_PROXY_PORT", socks5ProxyConfig.value(config_key::port).toString(protocols::socks5Proxy::defaultPort) } });
|
vars.append({ { "$SOCKS5_PROXY_PORT", socks5ProxyConfig.value(config_key::port).toString(protocols::socks5Proxy::defaultPort) } });
|
||||||
auto username = socks5ProxyConfig.value(config_key::userName).toString();
|
auto username = socks5ProxyConfig.value(config_key::userName).toString();
|
||||||
|
|
@ -835,7 +818,7 @@ ErrorCode ServerController::isServerDpkgBusy(const ServerCredentials &credential
|
||||||
|
|
||||||
if (stdOut.contains("Packet manager not found"))
|
if (stdOut.contains("Packet manager not found"))
|
||||||
return ErrorCode::ServerPacketManagerError;
|
return ErrorCode::ServerPacketManagerError;
|
||||||
if (stdOut.contains("fuser not installed") || stdOut.contains("cat not installed"))
|
if (stdOut.contains("fuser not installed"))
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
|
|
||||||
if (stdOut.isEmpty()) {
|
if (stdOut.isEmpty()) {
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,6 @@ namespace amnezia
|
||||||
ServerUserPasswordRequired = 210,
|
ServerUserPasswordRequired = 210,
|
||||||
ServerDockerOnCgroupsV2 = 211,
|
ServerDockerOnCgroupsV2 = 211,
|
||||||
ServerCgroupMountpoint = 212,
|
ServerCgroupMountpoint = 212,
|
||||||
DockerPullRateLimit = 213,
|
|
||||||
|
|
||||||
// Ssh connection errors
|
// Ssh connection errors
|
||||||
SshRequestDeniedError = 300,
|
SshRequestDeniedError = 300,
|
||||||
|
|
@ -118,8 +117,6 @@ namespace amnezia
|
||||||
ApiServicesMissingError = 1107,
|
ApiServicesMissingError = 1107,
|
||||||
ApiConfigLimitError = 1108,
|
ApiConfigLimitError = 1108,
|
||||||
ApiNotFoundError = 1109,
|
ApiNotFoundError = 1109,
|
||||||
ApiMigrationError = 1110,
|
|
||||||
ApiUpdateRequestError = 1111,
|
|
||||||
|
|
||||||
// QFile errors
|
// QFile errors
|
||||||
OpenError = 1200,
|
OpenError = 1200,
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ QString errorString(ErrorCode code) {
|
||||||
case(ErrorCode::ServerUserPasswordRequired): errorMessage = QObject::tr("The user's password is required"); break;
|
case(ErrorCode::ServerUserPasswordRequired): errorMessage = QObject::tr("The user's password is required"); break;
|
||||||
case(ErrorCode::ServerDockerOnCgroupsV2): errorMessage = QObject::tr("Docker error: runc doesn't work on cgroups v2"); break;
|
case(ErrorCode::ServerDockerOnCgroupsV2): errorMessage = QObject::tr("Docker error: runc doesn't work on cgroups v2"); break;
|
||||||
case(ErrorCode::ServerCgroupMountpoint): errorMessage = QObject::tr("Server error: cgroup mountpoint does not exist"); break;
|
case(ErrorCode::ServerCgroupMountpoint): errorMessage = QObject::tr("Server error: cgroup mountpoint does not exist"); break;
|
||||||
case(ErrorCode::DockerPullRateLimit): errorMessage = QObject::tr("Docker error: The pull rate limit has been reached"); break;
|
|
||||||
|
|
||||||
// Libssh errors
|
// Libssh errors
|
||||||
case(ErrorCode::SshRequestDeniedError): errorMessage = QObject::tr("SSH request was denied"); break;
|
case(ErrorCode::SshRequestDeniedError): errorMessage = QObject::tr("SSH request was denied"); break;
|
||||||
|
|
@ -75,8 +74,6 @@ QString errorString(ErrorCode code) {
|
||||||
case (ErrorCode::ApiServicesMissingError): errorMessage = QObject::tr("Missing list of available services"); break;
|
case (ErrorCode::ApiServicesMissingError): errorMessage = QObject::tr("Missing list of available services"); break;
|
||||||
case (ErrorCode::ApiConfigLimitError): errorMessage = QObject::tr("The limit of allowed configurations per subscription has been exceeded"); break;
|
case (ErrorCode::ApiConfigLimitError): errorMessage = QObject::tr("The limit of allowed configurations per subscription has been exceeded"); break;
|
||||||
case (ErrorCode::ApiNotFoundError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
case (ErrorCode::ApiNotFoundError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
||||||
case (ErrorCode::ApiMigrationError): errorMessage = QObject::tr("A migration error has occurred. Please contact our technical support"); break;
|
|
||||||
case (ErrorCode::ApiUpdateRequestError): errorMessage = QObject::tr("Please update the application to use this feature"); break;
|
|
||||||
|
|
||||||
// QFile errors
|
// QFile errors
|
||||||
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,8 @@ bool Daemon::activate(const InterfaceConfig& config) {
|
||||||
// set routing
|
// set routing
|
||||||
for (const IPAddress& ip : config.m_allowedIPAddressRanges) {
|
for (const IPAddress& ip : config.m_allowedIPAddressRanges) {
|
||||||
if (!wgutils()->updateRoutePrefix(ip)) {
|
if (!wgutils()->updateRoutePrefix(ip)) {
|
||||||
logger.debug() << "Routing configuration failed for" << ip.toString();
|
logger.debug() << "Routing configuration failed for"
|
||||||
|
<< logger.sensitive(ip.toString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -169,14 +170,11 @@ bool Daemon::maybeUpdateResolvers(const InterfaceConfig& config) {
|
||||||
if ((config.m_hopType == InterfaceConfig::MultiHopExit) ||
|
if ((config.m_hopType == InterfaceConfig::MultiHopExit) ||
|
||||||
(config.m_hopType == InterfaceConfig::SingleHop)) {
|
(config.m_hopType == InterfaceConfig::SingleHop)) {
|
||||||
QList<QHostAddress> resolvers;
|
QList<QHostAddress> resolvers;
|
||||||
resolvers.append(QHostAddress(config.m_primaryDnsServer));
|
resolvers.append(QHostAddress(config.m_dnsServer));
|
||||||
if (!config.m_secondaryDnsServer.isEmpty()) {
|
|
||||||
resolvers.append(QHostAddress(config.m_secondaryDnsServer));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the DNS is not the Gateway, it's a user defined DNS
|
// If the DNS is not the Gateway, it's a user defined DNS
|
||||||
// thus, not add any other :)
|
// thus, not add any other :)
|
||||||
if (config.m_primaryDnsServer == config.m_serverIpv4Gateway) {
|
if (config.m_dnsServer == config.m_serverIpv4Gateway) {
|
||||||
resolvers.append(QHostAddress(config.m_serverIpv6Gateway));
|
resolvers.append(QHostAddress(config.m_serverIpv6Gateway));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,26 +280,15 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
||||||
config.m_serverIpv4Gateway = obj.value("serverIpv4Gateway").toString();
|
config.m_serverIpv4Gateway = obj.value("serverIpv4Gateway").toString();
|
||||||
config.m_serverIpv6Gateway = obj.value("serverIpv6Gateway").toString();
|
config.m_serverIpv6Gateway = obj.value("serverIpv6Gateway").toString();
|
||||||
|
|
||||||
if (!obj.contains("primaryDnsServer")) {
|
if (!obj.contains("dnsServer")) {
|
||||||
config.m_primaryDnsServer = QString();
|
config.m_dnsServer = QString();
|
||||||
} else {
|
} else {
|
||||||
QJsonValue value = obj.value("primaryDnsServer");
|
QJsonValue value = obj.value("dnsServer");
|
||||||
if (!value.isString()) {
|
if (!value.isString()) {
|
||||||
logger.error() << "dnsServer is not a string";
|
logger.error() << "dnsServer is not a string";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
config.m_primaryDnsServer = value.toString();
|
config.m_dnsServer = value.toString();
|
||||||
}
|
|
||||||
|
|
||||||
if (!obj.contains("secondaryDnsServer")) {
|
|
||||||
config.m_secondaryDnsServer = QString();
|
|
||||||
} else {
|
|
||||||
QJsonValue value = obj.value("secondaryDnsServer");
|
|
||||||
if (!value.isString()) {
|
|
||||||
logger.error() << "dnsServer is not a string";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
config.m_secondaryDnsServer = value.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj.contains("hopType")) {
|
if (!obj.contains("hopType")) {
|
||||||
|
|
@ -384,9 +371,6 @@ 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 (!parseStringList(obj, "allowedDnsServers", config.m_allowedDnsServers)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.m_killSwitchEnabled = QVariant(obj.value("killSwitchOption").toString()).toBool();
|
config.m_killSwitchEnabled = QVariant(obj.value("killSwitchOption").toString()).toBool();
|
||||||
|
|
||||||
|
|
@ -405,13 +389,6 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
||||||
if (!obj.value("S2").isNull()) {
|
if (!obj.value("S2").isNull()) {
|
||||||
config.m_responsePacketJunkSize = obj.value("S2").toString();
|
config.m_responsePacketJunkSize = obj.value("S2").toString();
|
||||||
}
|
}
|
||||||
if (!obj.value("S3").isNull()) {
|
|
||||||
config.m_cookieReplyPacketJunkSize = obj.value("S3").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("S4").isNull()) {
|
|
||||||
config.m_transportPacketJunkSize = obj.value("S4").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!obj.value("H1").isNull()) {
|
if (!obj.value("H1").isNull()) {
|
||||||
config.m_initPacketMagicHeader = obj.value("H1").toString();
|
config.m_initPacketMagicHeader = obj.value("H1").toString();
|
||||||
}
|
}
|
||||||
|
|
@ -425,34 +402,6 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
|
||||||
config.m_transportPacketMagicHeader = obj.value("H4").toString();
|
config.m_transportPacketMagicHeader = obj.value("H4").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!obj.value("I1").isNull()) {
|
|
||||||
config.m_specialJunk["I1"] = obj.value("I1").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("I2").isNull()) {
|
|
||||||
config.m_specialJunk["I2"] = obj.value("I2").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("I3").isNull()) {
|
|
||||||
config.m_specialJunk["I3"] = obj.value("I3").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("I4").isNull()) {
|
|
||||||
config.m_specialJunk["I4"] = obj.value("I4").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("I5").isNull()) {
|
|
||||||
config.m_specialJunk["I5"] = obj.value("I5").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("J1").isNull()) {
|
|
||||||
config.m_controlledJunk["J1"] = obj.value("J1").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("J2").isNull()) {
|
|
||||||
config.m_controlledJunk["J2"] = obj.value("J2").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("J3").isNull()) {
|
|
||||||
config.m_controlledJunk["J3"] = obj.value("J3").toString();
|
|
||||||
}
|
|
||||||
if (!obj.value("Itime").isNull()) {
|
|
||||||
config.m_specialHandshakeTimeout = obj.value("Itime").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -495,7 +444,7 @@ bool Daemon::deactivate(bool emitSignals) {
|
||||||
|
|
||||||
m_connections.clear();
|
m_connections.clear();
|
||||||
// Delete the interface
|
// Delete the interface
|
||||||
return wgutils()->deleteInterface();
|
return wgutils()->deleteInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Daemon::logs() {
|
QString Daemon::logs() {
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,7 @@ QJsonObject InterfaceConfig::toJson() const {
|
||||||
(m_hopType == InterfaceConfig::SingleHop)) {
|
(m_hopType == InterfaceConfig::SingleHop)) {
|
||||||
json.insert("serverIpv4Gateway", QJsonValue(m_serverIpv4Gateway));
|
json.insert("serverIpv4Gateway", QJsonValue(m_serverIpv4Gateway));
|
||||||
json.insert("serverIpv6Gateway", QJsonValue(m_serverIpv6Gateway));
|
json.insert("serverIpv6Gateway", QJsonValue(m_serverIpv6Gateway));
|
||||||
json.insert("primaryDnsServer", QJsonValue(m_primaryDnsServer));
|
json.insert("dnsServer", QJsonValue(m_dnsServer));
|
||||||
json.insert("secondaryDnsServer", QJsonValue(m_secondaryDnsServer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonArray allowedIPAddesses;
|
QJsonArray allowedIPAddesses;
|
||||||
|
|
@ -49,13 +48,6 @@ QJsonObject InterfaceConfig::toJson() const {
|
||||||
}
|
}
|
||||||
json.insert("excludedAddresses", jsExcludedAddresses);
|
json.insert("excludedAddresses", jsExcludedAddresses);
|
||||||
|
|
||||||
|
|
||||||
QJsonArray jsAllowedDnsServers;
|
|
||||||
for (const QString& i : m_allowedDnsServers) {
|
|
||||||
jsAllowedDnsServers.append(QJsonValue(i));
|
|
||||||
}
|
|
||||||
json.insert("allowedDnsServers", jsAllowedDnsServers);
|
|
||||||
|
|
||||||
QJsonArray disabledApps;
|
QJsonArray disabledApps;
|
||||||
for (const QString& i : m_vpnDisabledApps) {
|
for (const QString& i : m_vpnDisabledApps) {
|
||||||
disabledApps.append(QJsonValue(i));
|
disabledApps.append(QJsonValue(i));
|
||||||
|
|
@ -101,15 +93,11 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
|
||||||
out << "MTU = " << m_deviceMTU << "\n";
|
out << "MTU = " << m_deviceMTU << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_primaryDnsServer.isNull()) {
|
if (!m_dnsServer.isNull()) {
|
||||||
QStringList dnsServers;
|
QStringList dnsServers(m_dnsServer);
|
||||||
dnsServers.append(m_primaryDnsServer);
|
|
||||||
if (!m_secondaryDnsServer.isNull()) {
|
|
||||||
dnsServers.append(m_secondaryDnsServer);
|
|
||||||
}
|
|
||||||
// If the DNS is not the Gateway, it's a user defined DNS
|
// If the DNS is not the Gateway, it's a user defined DNS
|
||||||
// thus, not add any other :)
|
// thus, not add any other :)
|
||||||
if (m_primaryDnsServer == m_serverIpv4Gateway) {
|
if (m_dnsServer == m_serverIpv4Gateway) {
|
||||||
dnsServers.append(m_serverIpv6Gateway);
|
dnsServers.append(m_serverIpv6Gateway);
|
||||||
}
|
}
|
||||||
out << "DNS = " << dnsServers.join(", ") << "\n";
|
out << "DNS = " << dnsServers.join(", ") << "\n";
|
||||||
|
|
@ -130,12 +118,6 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
|
||||||
if (!m_responsePacketJunkSize.isNull()) {
|
if (!m_responsePacketJunkSize.isNull()) {
|
||||||
out << "S2 = " << m_responsePacketJunkSize << "\n";
|
out << "S2 = " << m_responsePacketJunkSize << "\n";
|
||||||
}
|
}
|
||||||
if (!m_cookieReplyPacketJunkSize.isNull()) {
|
|
||||||
out << "S3 = " << m_cookieReplyPacketJunkSize << "\n";
|
|
||||||
}
|
|
||||||
if (!m_transportPacketJunkSize.isNull()) {
|
|
||||||
out << "S4 = " << m_transportPacketJunkSize << "\n";
|
|
||||||
}
|
|
||||||
if (!m_initPacketMagicHeader.isNull()) {
|
if (!m_initPacketMagicHeader.isNull()) {
|
||||||
out << "H1 = " << m_initPacketMagicHeader << "\n";
|
out << "H1 = " << m_initPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
@ -149,16 +131,6 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
|
||||||
out << "H4 = " << m_transportPacketMagicHeader << "\n";
|
out << "H4 = " << m_transportPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const QString& key : m_specialJunk.keys()) {
|
|
||||||
out << key << " = " << m_specialJunk[key] << "\n";
|
|
||||||
}
|
|
||||||
for (const QString& key : m_controlledJunk.keys()) {
|
|
||||||
out << key << " = " << m_controlledJunk[key] << "\n";
|
|
||||||
}
|
|
||||||
if (!m_specialHandshakeTimeout.isNull()) {
|
|
||||||
out << "Itime = " << m_specialHandshakeTimeout << "\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";
|
||||||
|
|
|
||||||
|
|
@ -32,14 +32,12 @@ class InterfaceConfig {
|
||||||
QString m_serverIpv4AddrIn;
|
QString m_serverIpv4AddrIn;
|
||||||
QString m_serverPskKey;
|
QString m_serverPskKey;
|
||||||
QString m_serverIpv6AddrIn;
|
QString m_serverIpv6AddrIn;
|
||||||
QString m_primaryDnsServer;
|
QString m_dnsServer;
|
||||||
QString m_secondaryDnsServer;
|
|
||||||
int m_serverPort = 0;
|
int m_serverPort = 0;
|
||||||
int m_deviceMTU = 1420;
|
int m_deviceMTU = 1420;
|
||||||
QList<IPAddress> m_allowedIPAddressRanges;
|
QList<IPAddress> m_allowedIPAddressRanges;
|
||||||
QStringList m_excludedAddresses;
|
QStringList m_excludedAddresses;
|
||||||
QStringList m_vpnDisabledApps;
|
QStringList m_vpnDisabledApps;
|
||||||
QStringList m_allowedDnsServers;
|
|
||||||
bool m_killSwitchEnabled;
|
bool m_killSwitchEnabled;
|
||||||
#if defined(MZ_ANDROID) || defined(MZ_IOS)
|
#if defined(MZ_ANDROID) || defined(MZ_IOS)
|
||||||
QString m_installationId;
|
QString m_installationId;
|
||||||
|
|
@ -50,15 +48,10 @@ class InterfaceConfig {
|
||||||
QString m_junkPacketMaxSize;
|
QString m_junkPacketMaxSize;
|
||||||
QString m_initPacketJunkSize;
|
QString m_initPacketJunkSize;
|
||||||
QString m_responsePacketJunkSize;
|
QString m_responsePacketJunkSize;
|
||||||
QString m_cookieReplyPacketJunkSize;
|
|
||||||
QString m_transportPacketJunkSize;
|
|
||||||
QString m_initPacketMagicHeader;
|
QString m_initPacketMagicHeader;
|
||||||
QString m_responsePacketMagicHeader;
|
QString m_responsePacketMagicHeader;
|
||||||
QString m_underloadPacketMagicHeader;
|
QString m_underloadPacketMagicHeader;
|
||||||
QString m_transportPacketMagicHeader;
|
QString m_transportPacketMagicHeader;
|
||||||
QMap<QString, QString> m_specialJunk;
|
|
||||||
QMap<QString, QString> m_controlledJunk;
|
|
||||||
QString m_specialHandshakeTimeout;
|
|
||||||
|
|
||||||
QJsonObject toJson() const;
|
QJsonObject toJson() const;
|
||||||
QString toWgConf(
|
QString toWgConf(
|
||||||
|
|
|
||||||
|
|
@ -26,21 +26,9 @@ set_target_properties(networkextension PROPERTIES
|
||||||
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
|
||||||
|
|
||||||
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks"
|
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks"
|
||||||
)
|
|
||||||
|
|
||||||
if(DEPLOY)
|
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
||||||
set_target_properties(networkextension PROPERTIES
|
)
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution"
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
|
|
||||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "distr ios.org.amnezia.AmneziaVPN"
|
|
||||||
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "dev ios.org.amnezia.AmneziaVPN"
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
set_target_properties(networkextension PROPERTIES
|
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set_target_properties(networkextension PROPERTIES
|
set_target_properties(networkextension PROPERTIES
|
||||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ LocalSocketController::LocalSocketController() {
|
||||||
m_socket = new QLocalSocket(this);
|
m_socket = new QLocalSocket(this);
|
||||||
connect(m_socket, &QLocalSocket::connected, this,
|
connect(m_socket, &QLocalSocket::connected, this,
|
||||||
&LocalSocketController::daemonConnected);
|
&LocalSocketController::daemonConnected);
|
||||||
connect(m_socket, &QLocalSocket::disconnected, this,
|
connect(m_socket, &QLocalSocket::disconnected, this,
|
||||||
[&] { errorOccurred(QLocalSocket::PeerClosedError); });
|
[&] { errorOccurred(QLocalSocket::PeerClosedError); });
|
||||||
connect(m_socket, &QLocalSocket::errorOccurred, this,
|
connect(m_socket, &QLocalSocket::errorOccurred, this,
|
||||||
&LocalSocketController::errorOccurred);
|
&LocalSocketController::errorOccurred);
|
||||||
|
|
@ -123,7 +123,6 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
|
|
||||||
int appSplitTunnelType = rawConfig.value(amnezia::config_key::appSplitTunnelType).toInt();
|
int appSplitTunnelType = rawConfig.value(amnezia::config_key::appSplitTunnelType).toInt();
|
||||||
QJsonArray splitTunnelApps = rawConfig.value(amnezia::config_key::splitTunnelApps).toArray();
|
QJsonArray splitTunnelApps = rawConfig.value(amnezia::config_key::splitTunnelApps).toArray();
|
||||||
QJsonArray allowedDns = rawConfig.value(amnezia::config_key::allowedDnsServers).toArray();
|
|
||||||
|
|
||||||
QJsonObject wgConfig = rawConfig.value(protocolName + "_config_data").toObject();
|
QJsonObject wgConfig = rawConfig.value(protocolName + "_config_data").toObject();
|
||||||
|
|
||||||
|
|
@ -135,7 +134,7 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
|
|
||||||
// set up IPv6 unique-local-address, ULA, with "fd00::/8" prefix, not globally routable.
|
// set up IPv6 unique-local-address, ULA, with "fd00::/8" prefix, not globally routable.
|
||||||
// this will be default IPv6 gateway, OS recognizes that IPv6 link is local and switches to IPv4.
|
// this will be default IPv6 gateway, OS recognizes that IPv6 link is local and switches to IPv4.
|
||||||
// Otherwise some OSes (Linux) try IPv6 forever and hang.
|
// Otherwise some OSes (Linux) try IPv6 forever and hang.
|
||||||
// https://en.wikipedia.org/wiki/Unique_local_address (RFC 4193)
|
// https://en.wikipedia.org/wiki/Unique_local_address (RFC 4193)
|
||||||
// https://man7.org/linux/man-pages/man5/gai.conf.5.html
|
// https://man7.org/linux/man-pages/man5/gai.conf.5.html
|
||||||
json.insert("deviceIpv6Address", "fd58:baa6:dead::1"); // simply "dead::1" is globally-routable, don't use it
|
json.insert("deviceIpv6Address", "fd58:baa6:dead::1"); // simply "dead::1" is globally-routable, don't use it
|
||||||
|
|
@ -149,14 +148,7 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
json.insert("serverPort", wgConfig.value(amnezia::config_key::port).toInt());
|
json.insert("serverPort", wgConfig.value(amnezia::config_key::port).toInt());
|
||||||
json.insert("serverIpv4Gateway", wgConfig.value(amnezia::config_key::hostName));
|
json.insert("serverIpv4Gateway", wgConfig.value(amnezia::config_key::hostName));
|
||||||
// json.insert("serverIpv6Gateway", QJsonValue(hop.m_server.ipv6Gateway()));
|
// json.insert("serverIpv6Gateway", QJsonValue(hop.m_server.ipv6Gateway()));
|
||||||
|
json.insert("dnsServer", rawConfig.value(amnezia::config_key::dns1));
|
||||||
json.insert("primaryDnsServer", rawConfig.value(amnezia::config_key::dns1));
|
|
||||||
|
|
||||||
// We don't use secondary DNS if primary DNS is AmneziaDNS
|
|
||||||
if (!rawConfig.value(amnezia::config_key::dns1).toString().
|
|
||||||
contains(amnezia::protocols::dns::amneziaDnsIp)) {
|
|
||||||
json.insert("secondaryDnsServer", rawConfig.value(amnezia::config_key::dns2));
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonArray jsAllowedIPAddesses;
|
QJsonArray jsAllowedIPAddesses;
|
||||||
|
|
||||||
|
|
@ -234,8 +226,6 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
|
|
||||||
json.insert("vpnDisabledApps", splitTunnelApps);
|
json.insert("vpnDisabledApps", splitTunnelApps);
|
||||||
|
|
||||||
json.insert("allowedDnsServers", allowedDns);
|
|
||||||
|
|
||||||
json.insert(amnezia::config_key::killSwitchOption, rawConfig.value(amnezia::config_key::killSwitchOption));
|
json.insert(amnezia::config_key::killSwitchOption, rawConfig.value(amnezia::config_key::killSwitchOption));
|
||||||
|
|
||||||
if (protocolName == amnezia::config_key::awg) {
|
if (protocolName == amnezia::config_key::awg) {
|
||||||
|
|
@ -244,61 +234,28 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
|
||||||
json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize));
|
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::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize));
|
||||||
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
|
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
|
||||||
json.insert(amnezia::config_key::cookieReplyPacketJunkSize, wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize));
|
|
||||||
json.insert(amnezia::config_key::transportPacketJunkSize, wgConfig.value(amnezia::config_key::transportPacketJunkSize));
|
|
||||||
json.insert(amnezia::config_key::initPacketMagicHeader, wgConfig.value(amnezia::config_key::initPacketMagicHeader));
|
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::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::specialJunk1, wgConfig.value(amnezia::config_key::specialJunk1));
|
|
||||||
json.insert(amnezia::config_key::specialJunk2, wgConfig.value(amnezia::config_key::specialJunk2));
|
|
||||||
json.insert(amnezia::config_key::specialJunk3, wgConfig.value(amnezia::config_key::specialJunk3));
|
|
||||||
json.insert(amnezia::config_key::specialJunk4, wgConfig.value(amnezia::config_key::specialJunk4));
|
|
||||||
json.insert(amnezia::config_key::specialJunk5, wgConfig.value(amnezia::config_key::specialJunk5));
|
|
||||||
json.insert(amnezia::config_key::controlledJunk1, wgConfig.value(amnezia::config_key::controlledJunk1));
|
|
||||||
json.insert(amnezia::config_key::controlledJunk2, wgConfig.value(amnezia::config_key::controlledJunk2));
|
|
||||||
json.insert(amnezia::config_key::controlledJunk3, wgConfig.value(amnezia::config_key::controlledJunk3));
|
|
||||||
json.insert(amnezia::config_key::specialHandshakeTimeout, wgConfig.value(amnezia::config_key::specialHandshakeTimeout));
|
|
||||||
} else if (!wgConfig.value(amnezia::config_key::junkPacketCount).isUndefined()
|
} else if (!wgConfig.value(amnezia::config_key::junkPacketCount).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::junkPacketMinSize).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::junkPacketMinSize).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::junkPacketMaxSize).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::junkPacketMaxSize).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::initPacketJunkSize).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::initPacketJunkSize).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::responsePacketJunkSize).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::responsePacketJunkSize).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::transportPacketJunkSize).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::initPacketMagicHeader).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::initPacketMagicHeader).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::responsePacketMagicHeader).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::responsePacketMagicHeader).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::underloadPacketMagicHeader).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::underloadPacketMagicHeader).isUndefined()
|
||||||
&& !wgConfig.value(amnezia::config_key::transportPacketMagicHeader).isUndefined()
|
&& !wgConfig.value(amnezia::config_key::transportPacketMagicHeader).isUndefined()) {
|
||||||
&& !wgConfig.value(amnezia::config_key::specialJunk1).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::specialJunk2).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::specialJunk3).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::specialJunk4).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::specialJunk5).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::controlledJunk1).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::controlledJunk2).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::controlledJunk3).isUndefined()
|
|
||||||
&& !wgConfig.value(amnezia::config_key::specialHandshakeTimeout).isUndefined()) {
|
|
||||||
json.insert(amnezia::config_key::junkPacketCount, wgConfig.value(amnezia::config_key::junkPacketCount));
|
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::junkPacketMinSize, wgConfig.value(amnezia::config_key::junkPacketMinSize));
|
||||||
json.insert(amnezia::config_key::junkPacketMaxSize, wgConfig.value(amnezia::config_key::junkPacketMaxSize));
|
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::initPacketJunkSize, wgConfig.value(amnezia::config_key::initPacketJunkSize));
|
||||||
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
|
json.insert(amnezia::config_key::responsePacketJunkSize, wgConfig.value(amnezia::config_key::responsePacketJunkSize));
|
||||||
json.insert(amnezia::config_key::cookieReplyPacketJunkSize, wgConfig.value(amnezia::config_key::cookieReplyPacketJunkSize));
|
|
||||||
json.insert(amnezia::config_key::transportPacketJunkSize, wgConfig.value(amnezia::config_key::transportPacketJunkSize));
|
|
||||||
json.insert(amnezia::config_key::initPacketMagicHeader, wgConfig.value(amnezia::config_key::initPacketMagicHeader));
|
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::responsePacketMagicHeader, wgConfig.value(amnezia::config_key::responsePacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
json.insert(amnezia::config_key::underloadPacketMagicHeader, wgConfig.value(amnezia::config_key::underloadPacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
json.insert(amnezia::config_key::transportPacketMagicHeader, wgConfig.value(amnezia::config_key::transportPacketMagicHeader));
|
||||||
json.insert(amnezia::config_key::specialJunk1, wgConfig.value(amnezia::config_key::specialJunk1));
|
|
||||||
json.insert(amnezia::config_key::specialJunk2, wgConfig.value(amnezia::config_key::specialJunk2));
|
|
||||||
json.insert(amnezia::config_key::specialJunk3, wgConfig.value(amnezia::config_key::specialJunk3));
|
|
||||||
json.insert(amnezia::config_key::specialJunk4, wgConfig.value(amnezia::config_key::specialJunk4));
|
|
||||||
json.insert(amnezia::config_key::specialJunk5, wgConfig.value(amnezia::config_key::specialJunk5));
|
|
||||||
json.insert(amnezia::config_key::controlledJunk1, wgConfig.value(amnezia::config_key::controlledJunk1));
|
|
||||||
json.insert(amnezia::config_key::controlledJunk2, wgConfig.value(amnezia::config_key::controlledJunk2));
|
|
||||||
json.insert(amnezia::config_key::controlledJunk3, wgConfig.value(amnezia::config_key::controlledJunk3));
|
|
||||||
json.insert(amnezia::config_key::specialHandshakeTimeout, wgConfig.value(amnezia::config_key::specialHandshakeTimeout));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write(json);
|
write(json);
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,7 @@ struct WGConfig: Decodable {
|
||||||
let initPacketMagicHeader, responsePacketMagicHeader: String?
|
let initPacketMagicHeader, responsePacketMagicHeader: String?
|
||||||
let underloadPacketMagicHeader, transportPacketMagicHeader: String?
|
let underloadPacketMagicHeader, transportPacketMagicHeader: String?
|
||||||
let junkPacketCount, junkPacketMinSize, junkPacketMaxSize: String?
|
let junkPacketCount, junkPacketMinSize, junkPacketMaxSize: String?
|
||||||
let initPacketJunkSize, responsePacketJunkSize, cookieReplyPacketJunkSize, transportPacketJunkSize: String?
|
let initPacketJunkSize, responsePacketJunkSize: String?
|
||||||
let specialJunk1, specialJunk2, specialJunk3, specialJunk4, specialJunk5: String?
|
|
||||||
let controlledJunk1, controlledJunk2, controlledJunk3: String?
|
|
||||||
let specialHandshakeTimeout: String?
|
|
||||||
let dns1: String
|
let dns1: String
|
||||||
let dns2: String
|
let dns2: String
|
||||||
let mtu: String
|
let mtu: String
|
||||||
|
|
@ -26,10 +23,7 @@ struct WGConfig: Decodable {
|
||||||
case initPacketMagicHeader = "H1", responsePacketMagicHeader = "H2"
|
case initPacketMagicHeader = "H1", responsePacketMagicHeader = "H2"
|
||||||
case underloadPacketMagicHeader = "H3", transportPacketMagicHeader = "H4"
|
case underloadPacketMagicHeader = "H3", transportPacketMagicHeader = "H4"
|
||||||
case junkPacketCount = "Jc", junkPacketMinSize = "Jmin", junkPacketMaxSize = "Jmax"
|
case junkPacketCount = "Jc", junkPacketMinSize = "Jmin", junkPacketMaxSize = "Jmax"
|
||||||
case initPacketJunkSize = "S1", responsePacketJunkSize = "S2", cookieReplyPacketJunkSize = "S3", transportPacketJunkSize = "S4"
|
case initPacketJunkSize = "S1", responsePacketJunkSize = "S2"
|
||||||
case specialJunk1 = "I1", specialJunk2 = "I2", specialJunk3 = "I3", specialJunk4 = "I4", specialJunk5 = "I5"
|
|
||||||
case controlledJunk1 = "J1", controlledJunk2 = "J2", controlledJunk3 = "J3"
|
|
||||||
case specialHandshakeTimeout = "Itime"
|
|
||||||
case dns1
|
case dns1
|
||||||
case dns2
|
case dns2
|
||||||
case mtu
|
case mtu
|
||||||
|
|
@ -46,59 +40,19 @@ struct WGConfig: Decodable {
|
||||||
}
|
}
|
||||||
|
|
||||||
var settings: String {
|
var settings: String {
|
||||||
guard junkPacketCount != nil else { return "" }
|
junkPacketCount == nil ? "" :
|
||||||
|
"""
|
||||||
var settingsLines: [String] = []
|
Jc = \(junkPacketCount!)
|
||||||
|
Jmin = \(junkPacketMinSize!)
|
||||||
// Required parameters when junkPacketCount is present
|
Jmax = \(junkPacketMaxSize!)
|
||||||
settingsLines.append("Jc = \(junkPacketCount!)")
|
S1 = \(initPacketJunkSize!)
|
||||||
settingsLines.append("Jmin = \(junkPacketMinSize!)")
|
S2 = \(responsePacketJunkSize!)
|
||||||
settingsLines.append("Jmax = \(junkPacketMaxSize!)")
|
H1 = \(initPacketMagicHeader!)
|
||||||
settingsLines.append("S1 = \(initPacketJunkSize!)")
|
H2 = \(responsePacketMagicHeader!)
|
||||||
settingsLines.append("S2 = \(responsePacketJunkSize!)")
|
H3 = \(underloadPacketMagicHeader!)
|
||||||
|
H4 = \(transportPacketMagicHeader!)
|
||||||
settingsLines.append("H1 = \(initPacketMagicHeader!)")
|
|
||||||
settingsLines.append("H2 = \(responsePacketMagicHeader!)")
|
|
||||||
settingsLines.append("H3 = \(underloadPacketMagicHeader!)")
|
|
||||||
settingsLines.append("H4 = \(transportPacketMagicHeader!)")
|
|
||||||
|
|
||||||
// Optional parameters - only add if not nil and not empty
|
"""
|
||||||
if let s3 = cookieReplyPacketJunkSize, !s3.isEmpty {
|
|
||||||
settingsLines.append("S3 = \(s3)")
|
|
||||||
}
|
|
||||||
if let s4 = transportPacketJunkSize, !s4.isEmpty {
|
|
||||||
settingsLines.append("S4 = \(s4)")
|
|
||||||
}
|
|
||||||
|
|
||||||
if let i1 = specialJunk1, !i1.isEmpty {
|
|
||||||
settingsLines.append("I1 = \(i1)")
|
|
||||||
}
|
|
||||||
if let i2 = specialJunk2, !i2.isEmpty {
|
|
||||||
settingsLines.append("I2 = \(i2)")
|
|
||||||
}
|
|
||||||
if let i3 = specialJunk3, !i3.isEmpty {
|
|
||||||
settingsLines.append("I3 = \(i3)")
|
|
||||||
}
|
|
||||||
if let i4 = specialJunk4, !i4.isEmpty {
|
|
||||||
settingsLines.append("I4 = \(i4)")
|
|
||||||
}
|
|
||||||
if let i5 = specialJunk5, !i5.isEmpty {
|
|
||||||
settingsLines.append("I5 = \(i5)")
|
|
||||||
}
|
|
||||||
if let j1 = controlledJunk1, !j1.isEmpty {
|
|
||||||
settingsLines.append("J1 = \(j1)")
|
|
||||||
}
|
|
||||||
if let j2 = controlledJunk2, !j2.isEmpty {
|
|
||||||
settingsLines.append("J2 = \(j2)")
|
|
||||||
}
|
|
||||||
if let j3 = controlledJunk3, !j3.isEmpty {
|
|
||||||
settingsLines.append("J3 = \(j3)")
|
|
||||||
}
|
|
||||||
if let itime = specialHandshakeTimeout, !itime.isEmpty {
|
|
||||||
settingsLines.append("Itime = \(itime)")
|
|
||||||
}
|
|
||||||
|
|
||||||
return settingsLines.joined(separator: "\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var str: String {
|
var str: String {
|
||||||
|
|
|
||||||
|
|
@ -507,8 +507,6 @@ bool IosController::setupWireGuard()
|
||||||
|
|
||||||
wgConfig.insert(config_key::initPacketJunkSize, config[config_key::initPacketJunkSize]);
|
wgConfig.insert(config_key::initPacketJunkSize, config[config_key::initPacketJunkSize]);
|
||||||
wgConfig.insert(config_key::responsePacketJunkSize, config[config_key::responsePacketJunkSize]);
|
wgConfig.insert(config_key::responsePacketJunkSize, config[config_key::responsePacketJunkSize]);
|
||||||
wgConfig.insert(config_key::cookieReplyPacketJunkSize, config[config_key::cookieReplyPacketJunkSize]);
|
|
||||||
wgConfig.insert(config_key::transportPacketJunkSize, config[config_key::transportPacketJunkSize]);
|
|
||||||
|
|
||||||
wgConfig.insert(config_key::junkPacketCount, config[config_key::junkPacketCount]);
|
wgConfig.insert(config_key::junkPacketCount, config[config_key::junkPacketCount]);
|
||||||
wgConfig.insert(config_key::junkPacketMinSize, config[config_key::junkPacketMinSize]);
|
wgConfig.insert(config_key::junkPacketMinSize, config[config_key::junkPacketMinSize]);
|
||||||
|
|
@ -607,23 +605,11 @@ bool IosController::setupAwg()
|
||||||
|
|
||||||
wgConfig.insert(config_key::initPacketJunkSize, config[config_key::initPacketJunkSize]);
|
wgConfig.insert(config_key::initPacketJunkSize, config[config_key::initPacketJunkSize]);
|
||||||
wgConfig.insert(config_key::responsePacketJunkSize, config[config_key::responsePacketJunkSize]);
|
wgConfig.insert(config_key::responsePacketJunkSize, config[config_key::responsePacketJunkSize]);
|
||||||
wgConfig.insert(config_key::cookieReplyPacketJunkSize, config[config_key::cookieReplyPacketJunkSize]);
|
|
||||||
wgConfig.insert(config_key::transportPacketJunkSize, config[config_key::transportPacketJunkSize]);
|
|
||||||
|
|
||||||
wgConfig.insert(config_key::junkPacketCount, config[config_key::junkPacketCount]);
|
wgConfig.insert(config_key::junkPacketCount, config[config_key::junkPacketCount]);
|
||||||
wgConfig.insert(config_key::junkPacketMinSize, config[config_key::junkPacketMinSize]);
|
wgConfig.insert(config_key::junkPacketMinSize, config[config_key::junkPacketMinSize]);
|
||||||
wgConfig.insert(config_key::junkPacketMaxSize, config[config_key::junkPacketMaxSize]);
|
wgConfig.insert(config_key::junkPacketMaxSize, config[config_key::junkPacketMaxSize]);
|
||||||
|
|
||||||
wgConfig.insert(config_key::specialJunk1, config[config_key::specialJunk1]);
|
|
||||||
wgConfig.insert(config_key::specialJunk2, config[config_key::specialJunk2]);
|
|
||||||
wgConfig.insert(config_key::specialJunk3, config[config_key::specialJunk3]);
|
|
||||||
wgConfig.insert(config_key::specialJunk4, config[config_key::specialJunk4]);
|
|
||||||
wgConfig.insert(config_key::specialJunk5, config[config_key::specialJunk5]);
|
|
||||||
wgConfig.insert(config_key::controlledJunk1, config[config_key::controlledJunk1]);
|
|
||||||
wgConfig.insert(config_key::controlledJunk2, config[config_key::controlledJunk2]);
|
|
||||||
wgConfig.insert(config_key::controlledJunk3, config[config_key::controlledJunk3]);
|
|
||||||
wgConfig.insert(config_key::specialHandshakeTimeout, config[config_key::specialHandshakeTimeout]);
|
|
||||||
|
|
||||||
QJsonDocument wgConfigDoc(wgConfig);
|
QJsonDocument wgConfigDoc(wgConfig);
|
||||||
QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact));
|
QString wgConfigDocStr(wgConfigDoc.toJson(QJsonDocument::Compact));
|
||||||
|
|
||||||
|
|
@ -808,9 +794,9 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||||
if (!qtController) return;
|
if (!qtController) return;
|
||||||
|
|
||||||
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
|
||||||
|
|
||||||
__block bool isAccepted = false;
|
__block bool isAccepted = false;
|
||||||
|
|
||||||
[activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
|
[activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
|
||||||
isAccepted = completed;
|
isAccepted = completed;
|
||||||
emit finished();
|
emit finished();
|
||||||
|
|
@ -822,11 +808,11 @@ bool IosController::shareText(const QStringList& filesToSend) {
|
||||||
popController.sourceView = qtController.view;
|
popController.sourceView = qtController.view;
|
||||||
popController.sourceRect = CGRectMake(100, 100, 100, 100);
|
popController.sourceRect = CGRectMake(100, 100, 100, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
||||||
wait.exec();
|
wait.exec();
|
||||||
|
|
||||||
return isAccepted;
|
return isAccepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -840,7 +826,7 @@ QString IosController::openFile() {
|
||||||
if (!qtController) return;
|
if (!qtController) return;
|
||||||
|
|
||||||
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
[qtController presentViewController:documentPicker animated:YES completion:nil];
|
||||||
|
|
||||||
__block QString filePath;
|
__block QString filePath;
|
||||||
|
|
||||||
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
|
||||||
|
|
@ -855,7 +841,7 @@ QString IosController::openFile() {
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
|
||||||
wait.exec();
|
wait.exec();
|
||||||
|
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,7 @@ IPUtilsLinux::~IPUtilsLinux() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IPUtilsLinux::addInterfaceIPs(const InterfaceConfig& config) {
|
bool IPUtilsLinux::addInterfaceIPs(const InterfaceConfig& config) {
|
||||||
bool ret = addIP4AddressToDevice(config);
|
return addIP4AddressToDevice(config) && addIP6AddressToDevice(config);
|
||||||
addIP6AddressToDevice(config);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
|
bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
|
||||||
|
|
@ -97,7 +95,7 @@ bool IPUtilsLinux::addIP4AddressToDevice(const InterfaceConfig& config) {
|
||||||
// Set ifr to interface
|
// Set ifr to interface
|
||||||
int ret = ioctl(sockfd, SIOCSIFADDR, &ifr);
|
int ret = ioctl(sockfd, SIOCSIFADDR, &ifr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
logger.error() << "Failed to set IPv4: " << deviceAddr
|
logger.error() << "Failed to set IPv4: " << logger.sensitive(deviceAddr)
|
||||||
<< "error:" << strerror(errno);
|
<< "error:" << strerror(errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +136,7 @@ bool IPUtilsLinux::addIP6AddressToDevice(const InterfaceConfig& config) {
|
||||||
// Set ifr6 to the interface
|
// Set ifr6 to the interface
|
||||||
ret = ioctl(sockfd, SIOCSIFADDR, &ifr6);
|
ret = ioctl(sockfd, SIOCSIFADDR, &ifr6);
|
||||||
if (ret && (errno != EEXIST)) {
|
if (ret && (errno != EEXIST)) {
|
||||||
logger.error() << "Failed to set IPv6: " << deviceAddr
|
logger.error() << "Failed to set IPv6: " << logger.sensitive(deviceAddr)
|
||||||
<< "error:" << strerror(errno);
|
<< "error:" << strerror(errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -455,6 +455,9 @@ void LinuxFirewall::updateDNSServers(const QStringList& servers)
|
||||||
|
|
||||||
void LinuxFirewall::updateAllowNets(const QStringList& servers)
|
void LinuxFirewall::updateAllowNets(const QStringList& servers)
|
||||||
{
|
{
|
||||||
|
static QStringList existingServers {};
|
||||||
|
|
||||||
|
existingServers = servers;
|
||||||
execute(QStringLiteral("iptables -F %1.110.allowNets").arg(kAnchorName));
|
execute(QStringLiteral("iptables -F %1.110.allowNets").arg(kAnchorName));
|
||||||
for (const QString& rule : getAllowRule(servers))
|
for (const QString& rule : getAllowRule(servers))
|
||||||
execute(QStringLiteral("iptables -A %1.110.allowNets %2").arg(kAnchorName, rule));
|
execute(QStringLiteral("iptables -A %1.110.allowNets %2").arg(kAnchorName, rule));
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@
|
||||||
#include "leakdetector.h"
|
#include "leakdetector.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
#include "killswitch.h"
|
|
||||||
|
|
||||||
constexpr const int WG_TUN_PROC_TIMEOUT = 5000;
|
constexpr const int WG_TUN_PROC_TIMEOUT = 5000;
|
||||||
constexpr const char* WG_RUNTIME_DIR = "/var/run/amneziawg";
|
constexpr const char* WG_RUNTIME_DIR = "/var/run/amneziawg";
|
||||||
|
|
||||||
|
|
@ -121,12 +119,6 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||||
if (!config.m_responsePacketJunkSize.isEmpty()) {
|
if (!config.m_responsePacketJunkSize.isEmpty()) {
|
||||||
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
||||||
}
|
}
|
||||||
if (!config.m_cookieReplyPacketJunkSize.isEmpty()) {
|
|
||||||
out << "s3=" << config.m_cookieReplyPacketJunkSize << "\n";
|
|
||||||
}
|
|
||||||
if (!config.m_transportPacketJunkSize.isEmpty()) {
|
|
||||||
out << "s4=" << config.m_transportPacketJunkSize << "\n";
|
|
||||||
}
|
|
||||||
if (!config.m_initPacketMagicHeader.isEmpty()) {
|
if (!config.m_initPacketMagicHeader.isEmpty()) {
|
||||||
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
@ -140,26 +132,13 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||||
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const QString& key : config.m_specialJunk.keys()) {
|
|
||||||
out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n";
|
|
||||||
}
|
|
||||||
for (const QString& key : config.m_controlledJunk.keys()) {
|
|
||||||
out << key.toLower() << "=" << config.m_controlledJunk.value(key) << "\n";
|
|
||||||
}
|
|
||||||
if (!config.m_specialHandshakeTimeout.isEmpty()) {
|
|
||||||
out << "itime=" << config.m_specialHandshakeTimeout << "\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);
|
||||||
} else {
|
} else {
|
||||||
if (config.m_killSwitchEnabled) {
|
if (config.m_killSwitchEnabled) {
|
||||||
FirewallParams params { };
|
FirewallParams params { };
|
||||||
params.dnsServers.append(config.m_primaryDnsServer);
|
params.dnsServers.append(config.m_dnsServer);
|
||||||
if (!config.m_secondaryDnsServer.isEmpty()) {
|
|
||||||
params.dnsServers.append(config.m_secondaryDnsServer);
|
|
||||||
}
|
|
||||||
if (config.m_allowedIPAddressRanges.contains(IPAddress("0.0.0.0/0"))) {
|
if (config.m_allowedIPAddressRanges.contains(IPAddress("0.0.0.0/0"))) {
|
||||||
params.blockAll = true;
|
params.blockAll = true;
|
||||||
if (config.m_excludedAddresses.size()) {
|
if (config.m_excludedAddresses.size()) {
|
||||||
|
|
@ -203,7 +182,7 @@ bool WireguardUtilsLinux::deleteInterface() {
|
||||||
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name"));
|
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name"));
|
||||||
|
|
||||||
// double-check + ensure our firewall is installed and enabled
|
// double-check + ensure our firewall is installed and enabled
|
||||||
KillSwitch::instance()->disableKillSwitch();
|
LinuxFirewall::uninstall();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ bool IPUtilsMacos::addIP4AddressToDevice(const InterfaceConfig& config) {
|
||||||
// Set ifr to interface
|
// Set ifr to interface
|
||||||
int ret = ioctl(sockfd, SIOCAIFADDR, &ifr);
|
int ret = ioctl(sockfd, SIOCAIFADDR, &ifr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
logger.error() << "Failed to set IPv4: " << deviceAddr
|
logger.error() << "Failed to set IPv4: " << logger.sensitive(deviceAddr)
|
||||||
<< "error:" << strerror(errno);
|
<< "error:" << strerror(errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ bool IPUtilsMacos::addIP6AddressToDevice(const InterfaceConfig& config) {
|
||||||
// Set ifr to interface
|
// Set ifr to interface
|
||||||
int ret = ioctl(sockfd, SIOCAIFADDR_IN6, &ifr6);
|
int ret = ioctl(sockfd, SIOCAIFADDR_IN6, &ifr6);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
logger.error() << "Failed to set IPv6: " << deviceAddr
|
logger.error() << "Failed to set IPv6: " << logger.sensitive(deviceAddr)
|
||||||
<< "error:" << strerror(errno);
|
<< "error:" << strerror(errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,16 +43,8 @@ namespace {
|
||||||
|
|
||||||
#include "macosfirewall.h"
|
#include "macosfirewall.h"
|
||||||
|
|
||||||
#include <QDir>
|
#define ResourceDir qApp->applicationDirPath() + "/pf"
|
||||||
#include <QStandardPaths>
|
#define DaemonDataDir qApp->applicationDirPath() + "/pf"
|
||||||
|
|
||||||
// Read-only rules bundled with the application.
|
|
||||||
#define ResourceDir (qApp->applicationDirPath() + "/pf")
|
|
||||||
|
|
||||||
// Writable location that does NOT live inside the signed bundle. Using a
|
|
||||||
// constant path under /Library/Application Support keeps the signature intact
|
|
||||||
// and is accessible to the root helper.
|
|
||||||
#define DaemonDataDir QStringLiteral("/Library/Application Support/AmneziaVPN/pf")
|
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
|
|
@ -129,8 +121,6 @@ void MacOSFirewall::install()
|
||||||
logger.info() << "Installing PF root anchor";
|
logger.info() << "Installing PF root anchor";
|
||||||
|
|
||||||
installRootAnchors();
|
installRootAnchors();
|
||||||
// Ensure writable directory exists, then store the token there.
|
|
||||||
QDir().mkpath(DaemonDataDir);
|
|
||||||
execute(QStringLiteral("pfctl -E 2>&1 | grep -F 'Token : ' | cut -c9- > '%1/pf.token'").arg(DaemonDataDir));
|
execute(QStringLiteral("pfctl -E 2>&1 | grep -F 'Token : ' | cut -c9- > '%1/pf.token'").arg(DaemonDataDir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ void MacosRouteMonitor::handleRtmDelete(const struct rt_msghdr* rtm,
|
||||||
for (const IPAddress& prefix : m_exclusionRoutes) {
|
for (const IPAddress& prefix : m_exclusionRoutes) {
|
||||||
if (prefix.address().protocol() == protocol) {
|
if (prefix.address().protocol() == protocol) {
|
||||||
logger.debug() << "Removing exclusion route to"
|
logger.debug() << "Removing exclusion route to"
|
||||||
<< prefix.toString();
|
<< logger.sensitive(prefix.toString());
|
||||||
rtmSendRoute(RTM_DELETE, prefix, rtm->rtm_index, nullptr);
|
rtmSendRoute(RTM_DELETE, prefix, rtm->rtm_index, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +259,7 @@ void MacosRouteMonitor::handleRtmUpdate(const struct rt_msghdr* rtm,
|
||||||
for (const IPAddress& prefix : m_exclusionRoutes) {
|
for (const IPAddress& prefix : m_exclusionRoutes) {
|
||||||
if (prefix.address().protocol() == protocol) {
|
if (prefix.address().protocol() == protocol) {
|
||||||
logger.debug() << "Updating exclusion route to"
|
logger.debug() << "Updating exclusion route to"
|
||||||
<< prefix.toString();
|
<< logger.sensitive(prefix.toString());
|
||||||
rtmSendRoute(rtm_type, prefix, ifindex, addrlist[1].constData());
|
rtmSendRoute(rtm_type, prefix, ifindex, addrlist[1].constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -510,7 +510,8 @@ bool MacosRouteMonitor::deleteRoute(const IPAddress& prefix, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacosRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
|
bool MacosRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
|
||||||
logger.debug() << "Adding exclusion route for" << prefix.toString();
|
logger.debug() << "Adding exclusion route for"
|
||||||
|
<< logger.sensitive(prefix.toString());
|
||||||
|
|
||||||
if (m_exclusionRoutes.contains(prefix)) {
|
if (m_exclusionRoutes.contains(prefix)) {
|
||||||
logger.warning() << "Exclusion route already exists";
|
logger.warning() << "Exclusion route already exists";
|
||||||
|
|
@ -535,7 +536,8 @@ bool MacosRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MacosRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
|
bool MacosRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
|
||||||
logger.debug() << "Deleting exclusion route for" << prefix.toString();
|
logger.debug() << "Deleting exclusion route for"
|
||||||
|
<< logger.sensitive(prefix.toString());
|
||||||
|
|
||||||
m_exclusionRoutes.removeAll(prefix);
|
m_exclusionRoutes.removeAll(prefix);
|
||||||
if (prefix.address().protocol() == QAbstractSocket::IPv4Protocol) {
|
if (prefix.address().protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@
|
||||||
#include "leakdetector.h"
|
#include "leakdetector.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
|
||||||
#include "killswitch.h"
|
|
||||||
|
|
||||||
constexpr const int WG_TUN_PROC_TIMEOUT = 5000;
|
constexpr const int WG_TUN_PROC_TIMEOUT = 5000;
|
||||||
constexpr const char* WG_RUNTIME_DIR = "/var/run/amneziawg";
|
constexpr const char* WG_RUNTIME_DIR = "/var/run/amneziawg";
|
||||||
|
|
||||||
|
|
@ -119,12 +117,6 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||||
if (!config.m_responsePacketJunkSize.isEmpty()) {
|
if (!config.m_responsePacketJunkSize.isEmpty()) {
|
||||||
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
out << "s2=" << config.m_responsePacketJunkSize << "\n";
|
||||||
}
|
}
|
||||||
if (!config.m_cookieReplyPacketJunkSize.isEmpty()) {
|
|
||||||
out << "s3=" << config.m_cookieReplyPacketJunkSize << "\n";
|
|
||||||
}
|
|
||||||
if (!config.m_transportPacketJunkSize.isEmpty()) {
|
|
||||||
out << "s4=" << config.m_transportPacketJunkSize << "\n";
|
|
||||||
}
|
|
||||||
if (!config.m_initPacketMagicHeader.isEmpty()) {
|
if (!config.m_initPacketMagicHeader.isEmpty()) {
|
||||||
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
out << "h1=" << config.m_initPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
@ -138,43 +130,30 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||||
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
out << "h4=" << config.m_transportPacketMagicHeader << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const QString& key : config.m_specialJunk.keys()) {
|
|
||||||
out << key.toLower() << "=" << config.m_specialJunk.value(key) << "\n";
|
|
||||||
}
|
|
||||||
for (const QString& key : config.m_controlledJunk.keys()) {
|
|
||||||
out << key.toLower() << "=" << config.m_controlledJunk.value(key) << "\n";
|
|
||||||
}
|
|
||||||
if (!config.m_specialHandshakeTimeout.isEmpty()) {
|
|
||||||
out << "itime=" << config.m_specialHandshakeTimeout << "\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);
|
||||||
} else {
|
} else {
|
||||||
if (config.m_killSwitchEnabled) {
|
if (config.m_killSwitchEnabled) {
|
||||||
FirewallParams params { };
|
FirewallParams params { };
|
||||||
params.dnsServers.append(config.m_primaryDnsServer);
|
params.dnsServers.append(config.m_dnsServer);
|
||||||
if (!config.m_secondaryDnsServer.isEmpty()) {
|
|
||||||
params.dnsServers.append(config.m_secondaryDnsServer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.m_allowedIPAddressRanges.contains(IPAddress("0.0.0.0/0"))) {
|
if (config.m_allowedIPAddressRanges.contains(IPAddress("0.0.0.0/0"))) {
|
||||||
params.blockAll = true;
|
params.blockAll = true;
|
||||||
if (config.m_excludedAddresses.size()) {
|
if (config.m_excludedAddresses.size()) {
|
||||||
params.allowNets = true;
|
params.allowNets = true;
|
||||||
foreach (auto net, config.m_excludedAddresses) {
|
foreach (auto net, config.m_excludedAddresses) {
|
||||||
params.allowAddrs.append(net.toUtf8());
|
params.allowAddrs.append(net.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
params.blockNets = true;
|
params.blockNets = true;
|
||||||
foreach (auto net, config.m_allowedIPAddressRanges) {
|
foreach (auto net, config.m_allowedIPAddressRanges) {
|
||||||
params.blockAddrs.append(net.toString());
|
params.blockAddrs.append(net.toString());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
applyFirewallRules(params);
|
||||||
}
|
}
|
||||||
applyFirewallRules(params);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (err == 0);
|
return (err == 0);
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +180,7 @@ bool WireguardUtilsMacos::deleteInterface() {
|
||||||
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name"));
|
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name"));
|
||||||
|
|
||||||
// double-check + ensure our firewall is installed and enabled
|
// double-check + ensure our firewall is installed and enabled
|
||||||
KillSwitch::instance()->disableKillSwitch();
|
MacOSFirewall::uninstall();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "platforms/windows/windowsutils.h"
|
#include "platforms/windows/windowsutils.h"
|
||||||
|
|
||||||
#include "killswitch.h"
|
|
||||||
|
|
||||||
#define IPV6_ADDRESS_SIZE 16
|
#define IPV6_ADDRESS_SIZE 16
|
||||||
|
|
||||||
// ID for the Firewall Sublayer
|
// ID for the Firewall Sublayer
|
||||||
|
|
@ -182,29 +180,16 @@ bool WindowsFirewall::enableInterface(int vpnAdapterIndex) {
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info() << "Enabling Killswitch Using Adapter:" << vpnAdapterIndex;
|
logger.info() << "Enabling firewall Using Adapter:" << vpnAdapterIndex;
|
||||||
if (vpnAdapterIndex < 0)
|
|
||||||
{
|
|
||||||
IPAddress allv4("0.0.0.0/0");
|
|
||||||
if (!blockTrafficTo(allv4, MED_WEIGHT,
|
|
||||||
"Block Internet", "killswitch")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
IPAddress allv6("::/0");
|
|
||||||
if (!blockTrafficTo(allv6, MED_WEIGHT,
|
|
||||||
"Block Internet", "killswitch")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
FW_OK(allowTrafficOfAdapter(vpnAdapterIndex, MED_WEIGHT,
|
FW_OK(allowTrafficOfAdapter(vpnAdapterIndex, MED_WEIGHT,
|
||||||
"Allow usage of VPN Adapter"));
|
"Allow usage of VPN Adapter"));
|
||||||
FW_OK(allowDHCPTraffic(MED_WEIGHT, "Allow DHCP Traffic"));
|
FW_OK(allowDHCPTraffic(MED_WEIGHT, "Allow DHCP Traffic"));
|
||||||
FW_OK(allowHyperVTraffic(MAX_WEIGHT, "Allow Hyper-V Traffic"));
|
FW_OK(allowHyperVTraffic(MED_WEIGHT, "Allow Hyper-V Traffic"));
|
||||||
FW_OK(allowTrafficForAppOnAll(getCurrentPath(), MAX_WEIGHT,
|
FW_OK(allowTrafficForAppOnAll(getCurrentPath(), MAX_WEIGHT,
|
||||||
"Allow all for AmneziaVPN.exe"));
|
"Allow all for AmneziaVPN.exe"));
|
||||||
FW_OK(blockTrafficOnPort(53, MED_WEIGHT, "Block all DNS"));
|
FW_OK(blockTrafficOnPort(53, MED_WEIGHT, "Block all DNS"));
|
||||||
FW_OK(allowLoopbackTraffic(MED_WEIGHT,
|
FW_OK(
|
||||||
"Allow Loopback traffic on device %1"));
|
allowLoopbackTraffic(MED_WEIGHT, "Allow Loopback traffic on device %1"));
|
||||||
|
|
||||||
logger.debug() << "Killswitch on! Rules:" << m_activeRules.length();
|
logger.debug() << "Killswitch on! Rules:" << m_activeRules.length();
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -241,37 +226,6 @@ bool WindowsFirewall::enableLanBypass(const QList<IPAddress>& ranges) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow unprotected traffic sent to the following address ranges.
|
|
||||||
bool WindowsFirewall::allowTrafficRange(const QStringList& ranges) {
|
|
||||||
// Start the firewall transaction
|
|
||||||
auto result = FwpmTransactionBegin(m_sessionHandle, NULL);
|
|
||||||
if (result != ERROR_SUCCESS) {
|
|
||||||
disableKillSwitch();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto cleanup = qScopeGuard([&] {
|
|
||||||
FwpmTransactionAbort0(m_sessionHandle);
|
|
||||||
disableKillSwitch();
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const QString& addr : ranges) {
|
|
||||||
logger.debug() << "Allow killswitch exclude: " << addr;
|
|
||||||
if (!allowTrafficTo(QHostAddress(addr), HIGH_WEIGHT, "Allow killswitch bypass traffic")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result = FwpmTransactionCommit0(m_sessionHandle);
|
|
||||||
if (result != ERROR_SUCCESS) {
|
|
||||||
logger.error() << "FwpmTransactionCommit0 failed with error:" << result;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup.dismiss();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool WindowsFirewall::enablePeerTraffic(const InterfaceConfig& config) {
|
bool WindowsFirewall::enablePeerTraffic(const InterfaceConfig& config) {
|
||||||
// Start the firewall transaction
|
// Start the firewall transaction
|
||||||
auto result = FwpmTransactionBegin(m_sessionHandle, NULL);
|
auto result = FwpmTransactionBegin(m_sessionHandle, NULL);
|
||||||
|
|
@ -291,15 +245,15 @@ bool WindowsFirewall::enablePeerTraffic(const InterfaceConfig& config) {
|
||||||
"Block Internet", config.m_serverPublicKey)) {
|
"Block Internet", config.m_serverPublicKey)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!config.m_primaryDnsServer.isEmpty()) {
|
if (!config.m_dnsServer.isEmpty()) {
|
||||||
if (!allowTrafficTo(QHostAddress(config.m_primaryDnsServer), 53, HIGH_WEIGHT,
|
if (!allowTrafficTo(QHostAddress(config.m_dnsServer), 53, HIGH_WEIGHT,
|
||||||
"Allow DNS-Server", config.m_serverPublicKey)) {
|
"Allow DNS-Server", config.m_serverPublicKey)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// In some cases, we might configure a 2nd DNS server for IPv6, however
|
// In some cases, we might configure a 2nd DNS server for IPv6, however
|
||||||
// this should probably be cleaned up by converting m_dnsServer into
|
// this should probably be cleaned up by converting m_dnsServer into
|
||||||
// a QStringList instead.
|
// a QStringList instead.
|
||||||
if (config.m_primaryDnsServer == config.m_serverIpv4Gateway) {
|
if (config.m_dnsServer == config.m_serverIpv4Gateway) {
|
||||||
if (!allowTrafficTo(QHostAddress(config.m_serverIpv6Gateway), 53,
|
if (!allowTrafficTo(QHostAddress(config.m_serverIpv6Gateway), 53,
|
||||||
HIGH_WEIGHT, "Allow extra IPv6 DNS-Server",
|
HIGH_WEIGHT, "Allow extra IPv6 DNS-Server",
|
||||||
config.m_serverPublicKey)) {
|
config.m_serverPublicKey)) {
|
||||||
|
|
@ -308,37 +262,12 @@ bool WindowsFirewall::enablePeerTraffic(const InterfaceConfig& config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!config.m_secondaryDnsServer.isEmpty()) {
|
|
||||||
if (!allowTrafficTo(QHostAddress(config.m_secondaryDnsServer), 53, HIGH_WEIGHT,
|
|
||||||
"Allow DNS-Server", config.m_serverPublicKey)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// In some cases, we might configure a 2nd DNS server for IPv6, however
|
|
||||||
// this should probably be cleaned up by converting m_dnsServer into
|
|
||||||
// a QStringList instead.
|
|
||||||
if (config.m_secondaryDnsServer == config.m_serverIpv4Gateway) {
|
|
||||||
if (!allowTrafficTo(QHostAddress(config.m_serverIpv6Gateway), 53,
|
|
||||||
HIGH_WEIGHT, "Allow extra IPv6 DNS-Server",
|
|
||||||
config.m_serverPublicKey)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const QString& dns : config.m_allowedDnsServers) {
|
|
||||||
logger.debug() << "Allow DNS: " << dns;
|
|
||||||
if (!allowTrafficTo(QHostAddress(dns), 53, HIGH_WEIGHT,
|
|
||||||
"Allow DNS-Server", config.m_serverPublicKey)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!config.m_excludedAddresses.empty()) {
|
if (!config.m_excludedAddresses.empty()) {
|
||||||
for (const QString& i : config.m_excludedAddresses) {
|
for (const QString& i : config.m_excludedAddresses) {
|
||||||
logger.debug() << "excludedAddresses range: " << i;
|
logger.debug() << "excludedAddresses range: " << i;
|
||||||
|
|
||||||
if (!allowTrafficTo(i, HIGH_WEIGHT,
|
if (!allowTrafficTo(i, HIGH_WEIGHT,
|
||||||
"Allow Ecxlude route", config.m_serverPublicKey)) {
|
"Allow Ecxlude route", config.m_serverPublicKey)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -384,41 +313,37 @@ bool WindowsFirewall::disablePeerTraffic(const QString& pubkey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsFirewall::disableKillSwitch() {
|
bool WindowsFirewall::disableKillSwitch() {
|
||||||
return KillSwitch::instance()->disableKillSwitch();
|
auto result = FwpmTransactionBegin(m_sessionHandle, NULL);
|
||||||
}
|
auto cleanup = qScopeGuard([&] {
|
||||||
|
|
||||||
bool WindowsFirewall::allowAllTraffic() {
|
|
||||||
auto result = FwpmTransactionBegin(m_sessionHandle, NULL);
|
|
||||||
auto cleanup = qScopeGuard([&] {
|
|
||||||
if (result != ERROR_SUCCESS) {
|
|
||||||
FwpmTransactionAbort0(m_sessionHandle);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (result != ERROR_SUCCESS) {
|
if (result != ERROR_SUCCESS) {
|
||||||
logger.error() << "FwpmTransactionBegin0 failed. Return value:.\n"
|
FwpmTransactionAbort0(m_sessionHandle);
|
||||||
<< result;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
if (result != ERROR_SUCCESS) {
|
||||||
|
logger.error() << "FwpmTransactionBegin0 failed. Return value:.\n"
|
||||||
|
<< result;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& filterID : m_peerRules.values()) {
|
for (const auto& filterID : m_peerRules.values()) {
|
||||||
FwpmFilterDeleteById0(m_sessionHandle, filterID);
|
FwpmFilterDeleteById0(m_sessionHandle, filterID);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& filterID : qAsConst(m_activeRules)) {
|
for (const auto& filterID : qAsConst(m_activeRules)) {
|
||||||
FwpmFilterDeleteById0(m_sessionHandle, filterID);
|
FwpmFilterDeleteById0(m_sessionHandle, filterID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit!
|
// Commit!
|
||||||
result = FwpmTransactionCommit0(m_sessionHandle);
|
result = FwpmTransactionCommit0(m_sessionHandle);
|
||||||
if (result != ERROR_SUCCESS) {
|
if (result != ERROR_SUCCESS) {
|
||||||
logger.error() << "FwpmTransactionCommit0 failed. Return value:.\n"
|
logger.error() << "FwpmTransactionCommit0 failed. Return value:.\n"
|
||||||
<< result;
|
<< result;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_peerRules.clear();
|
m_peerRules.clear();
|
||||||
m_activeRules.clear();
|
m_activeRules.clear();
|
||||||
logger.debug() << "Firewall Disabled!";
|
logger.debug() << "Firewall Disabled!";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsFirewall::allowTrafficForAppOnAll(const QString& exePath,
|
bool WindowsFirewall::allowTrafficForAppOnAll(const QString& exePath,
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,6 @@ class WindowsFirewall final : public QObject {
|
||||||
bool enablePeerTraffic(const InterfaceConfig& config);
|
bool enablePeerTraffic(const InterfaceConfig& config);
|
||||||
bool disablePeerTraffic(const QString& pubkey);
|
bool disablePeerTraffic(const QString& pubkey);
|
||||||
bool disableKillSwitch();
|
bool disableKillSwitch();
|
||||||
bool allowAllTraffic();
|
|
||||||
bool allowTrafficRange(const QStringList& ranges);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool initSublayer();
|
static bool initSublayer();
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,8 @@ void WindowsRouteMonitor::updateCapturedRoutes(int family, void* ptable) {
|
||||||
data->Age++;
|
data->Age++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
logger.debug() << "Capturing route to" << prefix.toString();
|
logger.debug() << "Capturing route to"
|
||||||
|
<< logger.sensitive(prefix.toString());
|
||||||
|
|
||||||
// Clone the route and direct it into the VPN tunnel.
|
// Clone the route and direct it into the VPN tunnel.
|
||||||
data = new MIB_IPFORWARD_ROW2;
|
data = new MIB_IPFORWARD_ROW2;
|
||||||
|
|
@ -353,7 +354,8 @@ void WindowsRouteMonitor::updateCapturedRoutes(int family, void* ptable) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug() << "Removing route capture for" << i.key().toString();
|
logger.debug() << "Removing route capture for"
|
||||||
|
<< logger.sensitive(i.key().toString());
|
||||||
|
|
||||||
// Otherwise, this route is no longer in use.
|
// Otherwise, this route is no longer in use.
|
||||||
DWORD result = DeleteIpForwardEntry2(data);
|
DWORD result = DeleteIpForwardEntry2(data);
|
||||||
|
|
@ -366,7 +368,8 @@ void WindowsRouteMonitor::updateCapturedRoutes(int family, void* ptable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
|
bool WindowsRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
|
||||||
logger.debug() << "Adding exclusion route for" << prefix.toString();
|
logger.debug() << "Adding exclusion route for"
|
||||||
|
<< logger.sensitive(prefix.toString());
|
||||||
|
|
||||||
// Silently ignore non-routeable addresses.
|
// Silently ignore non-routeable addresses.
|
||||||
QHostAddress addr = prefix.address();
|
QHostAddress addr = prefix.address();
|
||||||
|
|
@ -434,7 +437,7 @@ bool WindowsRouteMonitor::addExclusionRoute(const IPAddress& prefix) {
|
||||||
|
|
||||||
bool WindowsRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
|
bool WindowsRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
|
||||||
logger.debug() << "Deleting exclusion route for"
|
logger.debug() << "Deleting exclusion route for"
|
||||||
<< prefix.address().toString();
|
<< logger.sensitive(prefix.address().toString());
|
||||||
|
|
||||||
MIB_IPFORWARD_ROW2* data = m_exclusionRoutes.take(prefix);
|
MIB_IPFORWARD_ROW2* data = m_exclusionRoutes.take(prefix);
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
|
|
@ -444,7 +447,7 @@ bool WindowsRouteMonitor::deleteExclusionRoute(const IPAddress& prefix) {
|
||||||
DWORD result = DeleteIpForwardEntry2(data);
|
DWORD result = DeleteIpForwardEntry2(data);
|
||||||
if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) {
|
if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) {
|
||||||
logger.error() << "Failed to delete route to"
|
logger.error() << "Failed to delete route to"
|
||||||
<< prefix.toString()
|
<< logger.sensitive(prefix.toString())
|
||||||
<< "result:" << result;
|
<< "result:" << result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -462,7 +465,7 @@ void WindowsRouteMonitor::flushRouteTable(
|
||||||
DWORD result = DeleteIpForwardEntry2(data);
|
DWORD result = DeleteIpForwardEntry2(data);
|
||||||
if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) {
|
if ((result != ERROR_NOT_FOUND) && (result != NO_ERROR)) {
|
||||||
logger.error() << "Failed to delete route to"
|
logger.error() << "Failed to delete route to"
|
||||||
<< i.key().toString()
|
<< logger.sensitive(i.key().toString())
|
||||||
<< "result:" << result;
|
<< "result:" << result;
|
||||||
}
|
}
|
||||||
delete data;
|
delete data;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@
|
||||||
|
|
||||||
#include "leakdetector.h"
|
#include "leakdetector.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "platforms/windows/windowscommons.h"
|
||||||
|
#include "windowsdaemon.h"
|
||||||
#include "windowsfirewall.h"
|
#include "windowsfirewall.h"
|
||||||
|
|
||||||
#pragma comment(lib, "iphlpapi.lib")
|
#pragma comment(lib, "iphlpapi.lib")
|
||||||
|
|
@ -130,7 +132,6 @@ bool WireguardUtilsWindows::addInterface(const InterfaceConfig& config) {
|
||||||
// Enable the windows firewall
|
// Enable the windows firewall
|
||||||
NET_IFINDEX ifindex;
|
NET_IFINDEX ifindex;
|
||||||
ConvertInterfaceLuidToIndex(&luid, &ifindex);
|
ConvertInterfaceLuidToIndex(&luid, &ifindex);
|
||||||
m_firewall->allowAllTraffic();
|
|
||||||
m_firewall->enableInterface(ifindex);
|
m_firewall->enableInterface(ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,13 +269,6 @@ bool WireguardUtilsWindows::updateRoutePrefix(const IPAddress& prefix) {
|
||||||
if (result == ERROR_OBJECT_ALREADY_EXISTS) {
|
if (result == ERROR_OBJECT_ALREADY_EXISTS) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case for ipv6 route with disabled ipv6
|
|
||||||
if (prefix.address().protocol() == QAbstractSocket::IPv6Protocol
|
|
||||||
&& result == ERROR_NOT_FOUND) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != NO_ERROR) {
|
if (result != NO_ERROR) {
|
||||||
logger.error() << "Failed to create route to"
|
logger.error() << "Failed to create route to"
|
||||||
<< prefix.toString()
|
<< prefix.toString()
|
||||||
|
|
|
||||||
|
|
@ -171,11 +171,6 @@ ErrorCode OpenVpnProtocol::start()
|
||||||
return lastError();
|
return lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AMNEZIA_DESKTOP
|
|
||||||
IpcClient::Interface()->addKillSwitchAllowedRange(QStringList(NetworkUtilities::getIPAddress(
|
|
||||||
m_configData.value(amnezia::config_key::hostName).toString())));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Detect default gateway
|
// Detect default gateway
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
QProcess p;
|
QProcess p;
|
||||||
|
|
@ -343,7 +338,7 @@ void OpenVpnProtocol::updateVpnGateway(const QString &line)
|
||||||
// killSwitch toggle
|
// killSwitch toggle
|
||||||
if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
||||||
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
||||||
IpcClient::Interface()->enableKillSwitch(m_configData, netInterfaces.at(i).index());
|
IpcClient::Interface()->enableKillSwitch(QJsonObject(), netInterfaces.at(i).index());
|
||||||
}
|
}
|
||||||
m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
||||||
m_configData.insert("vpnGateway", m_vpnGateway);
|
m_configData.insert("vpnGateway", m_vpnGateway);
|
||||||
|
|
|
||||||
|
|
@ -72,21 +72,10 @@ namespace amnezia
|
||||||
constexpr char junkPacketMaxSize[] = "Jmax";
|
constexpr char junkPacketMaxSize[] = "Jmax";
|
||||||
constexpr char initPacketJunkSize[] = "S1";
|
constexpr char initPacketJunkSize[] = "S1";
|
||||||
constexpr char responsePacketJunkSize[] = "S2";
|
constexpr char responsePacketJunkSize[] = "S2";
|
||||||
constexpr char cookieReplyPacketJunkSize[] = "S3";
|
|
||||||
constexpr char transportPacketJunkSize[] = "S4";
|
|
||||||
constexpr char initPacketMagicHeader[] = "H1";
|
constexpr char initPacketMagicHeader[] = "H1";
|
||||||
constexpr char responsePacketMagicHeader[] = "H2";
|
constexpr char responsePacketMagicHeader[] = "H2";
|
||||||
constexpr char underloadPacketMagicHeader[] = "H3";
|
constexpr char underloadPacketMagicHeader[] = "H3";
|
||||||
constexpr char transportPacketMagicHeader[] = "H4";
|
constexpr char transportPacketMagicHeader[] = "H4";
|
||||||
constexpr char specialJunk1[] = "I1";
|
|
||||||
constexpr char specialJunk2[] = "I2";
|
|
||||||
constexpr char specialJunk3[] = "I3";
|
|
||||||
constexpr char specialJunk4[] = "I4";
|
|
||||||
constexpr char specialJunk5[] = "I5";
|
|
||||||
constexpr char controlledJunk1[] = "J1";
|
|
||||||
constexpr char controlledJunk2[] = "J2";
|
|
||||||
constexpr char controlledJunk3[] = "J3";
|
|
||||||
constexpr char specialHandshakeTimeout[] = "Itime";
|
|
||||||
|
|
||||||
constexpr char openvpn[] = "openvpn";
|
constexpr char openvpn[] = "openvpn";
|
||||||
constexpr char wireguard[] = "wireguard";
|
constexpr char wireguard[] = "wireguard";
|
||||||
|
|
@ -106,16 +95,12 @@ namespace amnezia
|
||||||
constexpr char splitTunnelApps[] = "splitTunnelApps";
|
constexpr char splitTunnelApps[] = "splitTunnelApps";
|
||||||
constexpr char appSplitTunnelType[] = "appSplitTunnelType";
|
constexpr char appSplitTunnelType[] = "appSplitTunnelType";
|
||||||
|
|
||||||
constexpr char allowedDnsServers[] = "allowedDnsServers";
|
|
||||||
|
|
||||||
constexpr char killSwitchOption[] = "killSwitchOption";
|
constexpr char killSwitchOption[] = "killSwitchOption";
|
||||||
|
|
||||||
constexpr char crc[] = "crc";
|
constexpr char crc[] = "crc";
|
||||||
|
|
||||||
constexpr char clientId[] = "clientId";
|
constexpr char clientId[] = "clientId";
|
||||||
|
|
||||||
constexpr char nameOverriddenByUser[] = "nameOverriddenByUser";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace protocols
|
namespace protocols
|
||||||
|
|
@ -227,22 +212,10 @@ namespace amnezia
|
||||||
constexpr char defaultJunkPacketMaxSize[] = "30";
|
constexpr char defaultJunkPacketMaxSize[] = "30";
|
||||||
constexpr char defaultInitPacketJunkSize[] = "15";
|
constexpr char defaultInitPacketJunkSize[] = "15";
|
||||||
constexpr char defaultResponsePacketJunkSize[] = "18";
|
constexpr char defaultResponsePacketJunkSize[] = "18";
|
||||||
constexpr char defaultCookieReplyPacketJunkSize[] = "20";
|
|
||||||
constexpr char defaultTransportPacketJunkSize[] = "23";
|
|
||||||
|
|
||||||
constexpr char defaultInitPacketMagicHeader[] = "1020325451";
|
constexpr char defaultInitPacketMagicHeader[] = "1020325451";
|
||||||
constexpr char defaultResponsePacketMagicHeader[] = "3288052141";
|
constexpr char defaultResponsePacketMagicHeader[] = "3288052141";
|
||||||
constexpr char defaultTransportPacketMagicHeader[] = "2528465083";
|
constexpr char defaultTransportPacketMagicHeader[] = "2528465083";
|
||||||
constexpr char defaultUnderloadPacketMagicHeader[] = "1766607858";
|
constexpr char defaultUnderloadPacketMagicHeader[] = "1766607858";
|
||||||
constexpr char defaultSpecialJunk1[] = "";
|
|
||||||
constexpr char defaultSpecialJunk2[] = "";
|
|
||||||
constexpr char defaultSpecialJunk3[] = "";
|
|
||||||
constexpr char defaultSpecialJunk4[] = "";
|
|
||||||
constexpr char defaultSpecialJunk5[] = "";
|
|
||||||
constexpr char defaultControlledJunk1[] = "";
|
|
||||||
constexpr char defaultControlledJunk2[] = "";
|
|
||||||
constexpr char defaultControlledJunk3[] = "";
|
|
||||||
constexpr char defaultSpecialHandshakeTimeout[] = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace socks5Proxy
|
namespace socks5Proxy
|
||||||
|
|
|
||||||
|
|
@ -98,13 +98,8 @@ ErrorCode XrayProtocol::startTun2Sock()
|
||||||
if (vpnState == Vpn::ConnectionState::Connected) {
|
if (vpnState == Vpn::ConnectionState::Connected) {
|
||||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||||
QList<QHostAddress> dnsAddr;
|
QList<QHostAddress> dnsAddr;
|
||||||
|
|
||||||
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns1).toString()));
|
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns1).toString()));
|
||||||
// We don't use secondary DNS if primary DNS is AmneziaDNS
|
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns2).toString()));
|
||||||
if (!m_configData.value(amnezia::config_key::dns1).toString().
|
|
||||||
contains(amnezia::protocols::dns::amneziaDnsIp)) {
|
|
||||||
dnsAddr.push_back(QHostAddress(m_configData.value(config_key::dns2).toString()));
|
|
||||||
}
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QThread::msleep(8000);
|
QThread::msleep(8000);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -139,7 +134,7 @@ ErrorCode XrayProtocol::startTun2Sock()
|
||||||
// killSwitch toggle
|
// killSwitch toggle
|
||||||
if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) {
|
||||||
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) {
|
||||||
IpcClient::Interface()->enableKillSwitch(m_configData, netInterfaces.at(i).index());
|
IpcClient::Interface()->enableKillSwitch(QJsonObject(), netInterfaces.at(i).index());
|
||||||
}
|
}
|
||||||
m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index());
|
||||||
m_configData.insert("vpnGateway", m_vpnGateway);
|
m_configData.insert("vpnGateway", m_vpnGateway);
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,6 @@
|
||||||
<file>ui/qml/Components/SettingsContainersListView.qml</file>
|
<file>ui/qml/Components/SettingsContainersListView.qml</file>
|
||||||
<file>ui/qml/Components/ShareConnectionDrawer.qml</file>
|
<file>ui/qml/Components/ShareConnectionDrawer.qml</file>
|
||||||
<file>ui/qml/Components/TransportProtoSelector.qml</file>
|
<file>ui/qml/Components/TransportProtoSelector.qml</file>
|
||||||
<file>ui/qml/Components/AddSitePanel.qml</file>
|
|
||||||
<file>ui/qml/Config/GlobalConfig.qml</file>
|
<file>ui/qml/Config/GlobalConfig.qml</file>
|
||||||
<file>ui/qml/Config/qmldir</file>
|
<file>ui/qml/Config/qmldir</file>
|
||||||
<file>ui/qml/Controls2/BackButtonType.qml</file>
|
<file>ui/qml/Controls2/BackButtonType.qml</file>
|
||||||
|
|
@ -144,9 +143,7 @@
|
||||||
<file>ui/qml/Controls2/DropDownType.qml</file>
|
<file>ui/qml/Controls2/DropDownType.qml</file>
|
||||||
<file>ui/qml/Controls2/FlickableType.qml</file>
|
<file>ui/qml/Controls2/FlickableType.qml</file>
|
||||||
<file>ui/qml/Controls2/Header2Type.qml</file>
|
<file>ui/qml/Controls2/Header2Type.qml</file>
|
||||||
<file>ui/qml/Controls2/BaseHeaderType.qml</file>
|
<file>ui/qml/Controls2/HeaderType.qml</file>
|
||||||
<file>ui/qml/Controls2/HeaderTypeWithButton.qml</file>
|
|
||||||
<file>ui/qml/Controls2/HeaderTypeWithSwitcher.qml</file>
|
|
||||||
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
|
<file>ui/qml/Controls2/HorizontalRadioButton.qml</file>
|
||||||
<file>ui/qml/Controls2/ImageButtonType.qml</file>
|
<file>ui/qml/Controls2/ImageButtonType.qml</file>
|
||||||
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
|
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
|
||||||
|
|
@ -202,8 +199,6 @@
|
||||||
<file>ui/qml/Pages2/PageSettingsBackup.qml</file>
|
<file>ui/qml/Pages2/PageSettingsBackup.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsConnection.qml</file>
|
<file>ui/qml/Pages2/PageSettingsConnection.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsDns.qml</file>
|
<file>ui/qml/Pages2/PageSettingsDns.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsKillSwitch.qml</file>
|
|
||||||
<file>ui/qml/Pages2/PageSettingsKillSwitchExceptions.qml</file>
|
|
||||||
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
|
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsServerData.qml</file>
|
<file>ui/qml/Pages2/PageSettingsServerData.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsServerInfo.qml</file>
|
<file>ui/qml/Pages2/PageSettingsServerInfo.qml</file>
|
||||||
|
|
@ -236,10 +231,6 @@
|
||||||
<file>ui/qml/Pages2/PageSettingsApiNativeConfigs.qml</file>
|
<file>ui/qml/Pages2/PageSettingsApiNativeConfigs.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsApiDevices.qml</file>
|
<file>ui/qml/Pages2/PageSettingsApiDevices.qml</file>
|
||||||
<file>images/controls/monitor.svg</file>
|
<file>images/controls/monitor.svg</file>
|
||||||
<file>ui/qml/Components/ApiPremV1MigrationDrawer.qml</file>
|
|
||||||
<file>ui/qml/Components/ApiPremV1SubListDrawer.qml</file>
|
|
||||||
<file>ui/qml/Components/OtpCodeDrawer.qml</file>
|
|
||||||
<file>ui/qml/Components/AwgTextField.qml</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/countriesFlags">
|
<qresource prefix="/countriesFlags">
|
||||||
<file>images/flagKit/ZW.svg</file>
|
<file>images/flagKit/ZW.svg</file>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "secure_qsettings.h"
|
#include "secure_qsettings.h"
|
||||||
|
|
||||||
#include "../client/3rd/QSimpleCrypto/src/include/QAead.h"
|
#include "QAead.h"
|
||||||
#include "../client/3rd/QSimpleCrypto/src/include/QBlockCipher.h"
|
#include "QBlockCipher.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
#include "../client/3rd/qtkeychain/qtkeychain/keychain.h"
|
#include "keychain.h"
|
||||||
|
|
||||||
class SecureQSettings : public QObject
|
class SecureQSettings : public QObject
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ RUN mkdir -p /opt/amnezia
|
||||||
RUN echo -e "#!/bin/bash\ntail -f /dev/null" > /opt/amnezia/start.sh
|
RUN echo -e "#!/bin/bash\ntail -f /dev/null" > /opt/amnezia/start.sh
|
||||||
RUN chmod a+x /opt/amnezia/start.sh
|
RUN chmod a+x /opt/amnezia/start.sh
|
||||||
|
|
||||||
# Tune network
|
# Tune network
|
||||||
RUN echo -e " \n\
|
RUN echo -e " \n\
|
||||||
fs.file-max = 51200 \n\
|
fs.file-max = 51200 \n\
|
||||||
\n\
|
\n\
|
||||||
|
|
@ -40,8 +40,7 @@ RUN echo -e " \n\
|
||||||
echo -e " \n\
|
echo -e " \n\
|
||||||
* soft nofile 51200 \n\
|
* soft nofile 51200 \n\
|
||||||
* hard nofile 51200 \n\
|
* hard nofile 51200 \n\
|
||||||
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
|
" | sed -e 's/^\s\+//g' | tee -a /etc/security/limits.conf
|
||||||
|
|
||||||
ENTRYPOINT [ "dumb-init", "/opt/amnezia/start.sh" ]
|
ENTRYPOINT [ "dumb-init", "/opt/amnezia/start.sh" ]
|
||||||
CMD [ "" ]
|
CMD [ "" ]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,5 +23,4 @@ H1 = $INIT_PACKET_MAGIC_HEADER
|
||||||
H2 = $RESPONSE_PACKET_MAGIC_HEADER
|
H2 = $RESPONSE_PACKET_MAGIC_HEADER
|
||||||
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
|
H3 = $UNDERLOAD_PACKET_MAGIC_HEADER
|
||||||
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
|
H4 = $TRANSPORT_PACKET_MAGIC_HEADER
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
if which apt-get > /dev/null 2>&1; then LOCK_CMD="fuser"; LOCK_FILE="/var/lib/dpkg/lock-frontend";\
|
if which apt-get > /dev/null 2>&1; then LOCK_FILE="/var/lib/dpkg/lock-frontend";\
|
||||||
elif which dnf > /dev/null 2>&1; then LOCK_CMD="fuser"; LOCK_FILE="/var/cache/dnf/* /var/run/dnf/* /var/lib/dnf/* /var/lib/rpm/*";\
|
elif which dnf > /dev/null 2>&1; then LOCK_FILE="/var/run/dnf.pid";\
|
||||||
elif which yum > /dev/null 2>&1; then LOCK_CMD="cat"; LOCK_FILE="/var/run/yum.pid";\
|
elif which yum > /dev/null 2>&1; then LOCK_FILE="/var/run/yum.pid";\
|
||||||
elif which zypper > /dev/null 2>&1; then LOCK_CMD="cat"; LOCK_FILE="/var/run/zypp.pid";\
|
elif which pacman > /dev/null 2>&1; then LOCK_FILE="/var/lib/pacman/db.lck";\
|
||||||
elif which pacman > /dev/null 2>&1; then LOCK_CMD="fuser"; LOCK_FILE="/var/lib/pacman/db.lck";\
|
|
||||||
else echo "Packet manager not found"; echo "Internal error"; exit 1; fi;\
|
else echo "Packet manager not found"; echo "Internal error"; exit 1; fi;\
|
||||||
if command -v $LOCK_CMD > /dev/null 2>&1; then sudo $LOCK_CMD $LOCK_FILE 2>/dev/null; else echo "$LOCK_CMD not installed"; fi
|
if command -v fuser > /dev/null 2>&1; then sudo fuser $LOCK_FILE 2>/dev/null; else echo "fuser not installed"; fi
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); opt="--version";\
|
if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); opt="--version";\
|
||||||
elif which dnf > /dev/null 2>&1; then pm=$(which dnf); opt="--version";\
|
elif which dnf > /dev/null 2>&1; then pm=$(which dnf); opt="--version";\
|
||||||
elif which yum > /dev/null 2>&1; then pm=$(which yum); opt="--version";\
|
elif which yum > /dev/null 2>&1; then pm=$(which yum); opt="--version";\
|
||||||
elif which zypper > /dev/null 2>&1; then pm=$(which zypper); opt="--version";\
|
|
||||||
elif which pacman > /dev/null 2>&1; then pm=$(which pacman); opt="--version";\
|
elif which pacman > /dev/null 2>&1; then pm=$(which pacman); opt="--version";\
|
||||||
else pm="uname"; opt="-a";\
|
else pm="uname"; opt="-a";\
|
||||||
fi;\
|
fi;\
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); silent_inst="-yq install"; check_pkgs="-yq update"; docker_pkg="docker.io"; dist="debian";\
|
if which apt-get > /dev/null 2>&1; then pm=$(which apt-get); silent_inst="-yq install"; check_pkgs="-yq update"; docker_pkg="docker.io"; dist="debian";\
|
||||||
elif which dnf > /dev/null 2>&1; then pm=$(which dnf); silent_inst="-yq install"; check_pkgs="-yq check-update"; docker_pkg="docker"; dist="fedora";\
|
elif which dnf > /dev/null 2>&1; then pm=$(which dnf); silent_inst="-yq install"; check_pkgs="-yq check-update"; docker_pkg="docker"; dist="fedora";\
|
||||||
elif which yum > /dev/null 2>&1; then pm=$(which yum); silent_inst="-y -q install"; check_pkgs="-y -q check-update"; docker_pkg="docker"; dist="centos";\
|
elif which yum > /dev/null 2>&1; then pm=$(which yum); silent_inst="-y -q install"; check_pkgs="-y -q check-update"; docker_pkg="docker"; dist="centos";\
|
||||||
elif which zypper > /dev/null 2>&1; then pm=$(which zypper); silent_inst="-nq install"; check_pkgs="-nq refresh"; docker_pkg="docker"; dist="opensuse";\
|
|
||||||
elif which pacman > /dev/null 2>&1; then pm=$(which pacman); silent_inst="-S --noconfirm --noprogressbar --quiet"; check_pkgs="-Sup"; docker_pkg="docker"; dist="archlinux";\
|
elif which pacman > /dev/null 2>&1; then pm=$(which pacman); silent_inst="-S --noconfirm --noprogressbar --quiet"; check_pkgs="-Sup"; docker_pkg="docker"; dist="archlinux";\
|
||||||
else echo "Packet manager not found"; exit 1; fi;\
|
else echo "Packet manager not found"; exit 1; fi;\
|
||||||
echo "Dist: $dist, Packet manager: $pm, Install command: $silent_inst, Check pkgs command: $check_pkgs, Docker pkg: $docker_pkg";\
|
echo "Dist: $dist, Packet manager: $pm, Install command: $silent_inst, Check pkgs command: $check_pkgs, Docker pkg: $docker_pkg";\
|
||||||
|
|
|
||||||
|
|
@ -443,16 +443,6 @@ void Settings::setKillSwitchEnabled(bool enabled)
|
||||||
setValue("Conf/killSwitchEnabled", enabled);
|
setValue("Conf/killSwitchEnabled", enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::isStrictKillSwitchEnabled() const
|
|
||||||
{
|
|
||||||
return value("Conf/strictKillSwitchEnabled", false).toBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::setStrictKillSwitchEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
setValue("Conf/strictKillSwitchEnabled", enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Settings::getInstallationUuid(const bool needCreate)
|
QString Settings::getInstallationUuid(const bool needCreate)
|
||||||
{
|
{
|
||||||
auto uuid = value("Conf/installationUuid", "").toString();
|
auto uuid = value("Conf/installationUuid", "").toString();
|
||||||
|
|
@ -558,23 +548,3 @@ void Settings::disableHomeAdLabel()
|
||||||
{
|
{
|
||||||
setValue("Conf/homeAdLabelVisible", false);
|
setValue("Conf/homeAdLabelVisible", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::isPremV1MigrationReminderActive()
|
|
||||||
{
|
|
||||||
return value("Conf/premV1MigrationReminderActive", true).toBool();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::disablePremV1MigrationReminder()
|
|
||||||
{
|
|
||||||
setValue("Conf/premV1MigrationReminderActive", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Settings::allowedDnsServers() const
|
|
||||||
{
|
|
||||||
return value("Conf/allowedDnsServers").toStringList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::setAllowedDnsServers(const QStringList &servers)
|
|
||||||
{
|
|
||||||
setValue("Conf/allowedDnsServers", servers);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -174,12 +174,11 @@ public:
|
||||||
|
|
||||||
QLocale getAppLanguage()
|
QLocale getAppLanguage()
|
||||||
{
|
{
|
||||||
QString localeStr = m_settings.value("Conf/appLanguage").toString();
|
return value("Conf/appLanguage", QLocale()).toLocale();
|
||||||
return QLocale(localeStr);
|
|
||||||
};
|
};
|
||||||
void setAppLanguage(QLocale locale)
|
void setAppLanguage(QLocale locale)
|
||||||
{
|
{
|
||||||
setValue("Conf/appLanguage", locale.name());
|
setValue("Conf/appLanguage", locale);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isScreenshotsEnabled() const
|
bool isScreenshotsEnabled() const
|
||||||
|
|
@ -214,10 +213,6 @@ public:
|
||||||
|
|
||||||
bool isKillSwitchEnabled() const;
|
bool isKillSwitchEnabled() const;
|
||||||
void setKillSwitchEnabled(bool enabled);
|
void setKillSwitchEnabled(bool enabled);
|
||||||
|
|
||||||
bool isStrictKillSwitchEnabled() const;
|
|
||||||
void setStrictKillSwitchEnabled(bool enabled);
|
|
||||||
|
|
||||||
QString getInstallationUuid(const bool needCreate);
|
QString getInstallationUuid(const bool needCreate);
|
||||||
|
|
||||||
void resetGatewayEndpoint();
|
void resetGatewayEndpoint();
|
||||||
|
|
@ -230,12 +225,6 @@ public:
|
||||||
bool isHomeAdLabelVisible();
|
bool isHomeAdLabelVisible();
|
||||||
void disableHomeAdLabel();
|
void disableHomeAdLabel();
|
||||||
|
|
||||||
bool isPremV1MigrationReminderActive();
|
|
||||||
void disablePremV1MigrationReminder();
|
|
||||||
|
|
||||||
QStringList allowedDnsServers() const;
|
|
||||||
void setAllowedDnsServers(const QStringList &servers);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void saveLogsChanged(bool enabled);
|
void saveLogsChanged(bool enabled);
|
||||||
void screenshotsEnabledChanged(bool enabled);
|
void screenshotsEnabledChanged(bool enabled);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
34
client/ui/Controls2
Normal file
34
client/ui/Controls2
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
TextArea {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
topPadding: 16
|
||||||
|
leftPadding: 16
|
||||||
|
|
||||||
|
color: "#D7D8DB"
|
||||||
|
selectionColor: "#412102"
|
||||||
|
selectedTextColor: "#D7D8DB"
|
||||||
|
placeholderTextColor: "#878B91"
|
||||||
|
|
||||||
|
font.pixelSize: 16
|
||||||
|
font.weight: Font.Medium
|
||||||
|
font.family: "PT Root UI VF"
|
||||||
|
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.RightButton
|
||||||
|
onClicked: contextMenu.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextMenuType {
|
||||||
|
id: contextMenu
|
||||||
|
textObj: textField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
#include "allowedDnsController.h"
|
|
||||||
|
|
||||||
#include <QFile>
|
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "systemController.h"
|
|
||||||
#include "core/networkUtilities.h"
|
|
||||||
#include "core/defs.h"
|
|
||||||
|
|
||||||
AllowedDnsController::AllowedDnsController(const std::shared_ptr<Settings> &settings,
|
|
||||||
const QSharedPointer<AllowedDnsModel> &allowedDnsModel,
|
|
||||||
QObject *parent)
|
|
||||||
: QObject(parent), m_settings(settings), m_allowedDnsModel(allowedDnsModel)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllowedDnsController::addDns(QString ip)
|
|
||||||
{
|
|
||||||
if (ip.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NetworkUtilities::ipAddressRegExp().match(ip).hasMatch()) {
|
|
||||||
emit errorOccurred(tr("The address does not look like a valid IP address"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_allowedDnsModel->addDns(ip)) {
|
|
||||||
emit finished(tr("New DNS server added: %1").arg(ip));
|
|
||||||
} else {
|
|
||||||
emit errorOccurred(tr("DNS server already exists: %1").arg(ip));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllowedDnsController::removeDns(int index)
|
|
||||||
{
|
|
||||||
auto modelIndex = m_allowedDnsModel->index(index);
|
|
||||||
auto ip = m_allowedDnsModel->data(modelIndex, AllowedDnsModel::Roles::IpRole).toString();
|
|
||||||
m_allowedDnsModel->removeDns(modelIndex);
|
|
||||||
|
|
||||||
emit finished(tr("DNS server removed: %1").arg(ip));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllowedDnsController::importDns(const QString &fileName, bool replaceExisting)
|
|
||||||
{
|
|
||||||
QByteArray jsonData;
|
|
||||||
if (!SystemController::readFile(fileName, jsonData)) {
|
|
||||||
emit errorOccurred(tr("Can't open file: %1").arg(fileName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonData);
|
|
||||||
if (jsonDocument.isNull()) {
|
|
||||||
emit errorOccurred(tr("Failed to parse JSON data from file: %1").arg(fileName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!jsonDocument.isArray()) {
|
|
||||||
emit errorOccurred(tr("The JSON data is not an array in file: %1").arg(fileName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto jsonArray = jsonDocument.array();
|
|
||||||
QStringList dnsServers;
|
|
||||||
|
|
||||||
for (auto jsonValue : jsonArray) {
|
|
||||||
auto ip = jsonValue.toString();
|
|
||||||
|
|
||||||
if (!NetworkUtilities::ipAddressRegExp().match(ip).hasMatch()) {
|
|
||||||
qDebug() << ip << " is not a valid IP address";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
dnsServers.append(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_allowedDnsModel->addDnsList(dnsServers, replaceExisting);
|
|
||||||
|
|
||||||
emit finished(tr("Import completed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllowedDnsController::exportDns(const QString &fileName)
|
|
||||||
{
|
|
||||||
auto dnsServers = m_allowedDnsModel->getCurrentDnsServers();
|
|
||||||
|
|
||||||
QJsonArray jsonArray;
|
|
||||||
|
|
||||||
for (const auto &ip : dnsServers) {
|
|
||||||
jsonArray.append(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonDocument jsonDocument(jsonArray);
|
|
||||||
QByteArray jsonData = jsonDocument.toJson();
|
|
||||||
|
|
||||||
SystemController::saveFile(fileName, jsonData);
|
|
||||||
|
|
||||||
emit finished(tr("Export completed"));
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
#ifndef ALLOWEDDNSCONTROLLER_H
|
|
||||||
#define ALLOWEDDNSCONTROLLER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include "settings.h"
|
|
||||||
#include "ui/models/allowed_dns_model.h"
|
|
||||||
|
|
||||||
class AllowedDnsController : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AllowedDnsController(const std::shared_ptr<Settings> &settings,
|
|
||||||
const QSharedPointer<AllowedDnsModel> &allowedDnsModel,
|
|
||||||
QObject *parent = nullptr);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void addDns(QString ip);
|
|
||||||
void removeDns(int index);
|
|
||||||
|
|
||||||
void importDns(const QString &fileName, bool replaceExisting);
|
|
||||||
void exportDns(const QString &fileName);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void errorOccurred(const QString &errorMessage);
|
|
||||||
void finished(const QString &message);
|
|
||||||
|
|
||||||
void saveFile(const QString &fileName, const QString &data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
|
||||||
QSharedPointer<AllowedDnsModel> m_allowedDnsModel;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ALLOWEDDNSCONTROLLER_H
|
|
||||||
|
|
@ -18,7 +18,6 @@ namespace
|
||||||
{
|
{
|
||||||
constexpr char cloak[] = "cloak";
|
constexpr char cloak[] = "cloak";
|
||||||
constexpr char awg[] = "awg";
|
constexpr char awg[] = "awg";
|
||||||
constexpr char vless[] = "vless";
|
|
||||||
|
|
||||||
constexpr char apiEndpoint[] = "api_endpoint";
|
constexpr char apiEndpoint[] = "api_endpoint";
|
||||||
constexpr char accessToken[] = "api_key";
|
constexpr char accessToken[] = "api_key";
|
||||||
|
|
@ -36,6 +35,10 @@ namespace
|
||||||
constexpr char serviceInfo[] = "service_info";
|
constexpr char serviceInfo[] = "service_info";
|
||||||
constexpr char serviceProtocol[] = "service_protocol";
|
constexpr char serviceProtocol[] = "service_protocol";
|
||||||
|
|
||||||
|
constexpr char aesKey[] = "aes_key";
|
||||||
|
constexpr char aesIv[] = "aes_iv";
|
||||||
|
constexpr char aesSalt[] = "aes_salt";
|
||||||
|
|
||||||
constexpr char apiPayload[] = "api_payload";
|
constexpr char apiPayload[] = "api_payload";
|
||||||
constexpr char keyPayload[] = "key_payload";
|
constexpr char keyPayload[] = "key_payload";
|
||||||
|
|
||||||
|
|
@ -44,185 +47,6 @@ namespace
|
||||||
|
|
||||||
constexpr char config[] = "config";
|
constexpr char config[] = "config";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProtocolData
|
|
||||||
{
|
|
||||||
OpenVpnConfigurator::ConnectionData certRequest;
|
|
||||||
|
|
||||||
QString wireGuardClientPrivKey;
|
|
||||||
QString wireGuardClientPubKey;
|
|
||||||
|
|
||||||
QString xrayUuid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GatewayRequestData
|
|
||||||
{
|
|
||||||
QString osVersion;
|
|
||||||
QString appVersion;
|
|
||||||
|
|
||||||
QString installationUuid;
|
|
||||||
|
|
||||||
QString userCountryCode;
|
|
||||||
QString serverCountryCode;
|
|
||||||
QString serviceType;
|
|
||||||
QString serviceProtocol;
|
|
||||||
|
|
||||||
QJsonObject authData;
|
|
||||||
|
|
||||||
QJsonObject toJsonObject() const
|
|
||||||
{
|
|
||||||
QJsonObject obj;
|
|
||||||
if (!osVersion.isEmpty()) {
|
|
||||||
obj[configKey::osVersion] = osVersion;
|
|
||||||
}
|
|
||||||
if (!appVersion.isEmpty()) {
|
|
||||||
obj[configKey::appVersion] = appVersion;
|
|
||||||
}
|
|
||||||
if (!installationUuid.isEmpty()) {
|
|
||||||
obj[configKey::uuid] = installationUuid;
|
|
||||||
}
|
|
||||||
if (!userCountryCode.isEmpty()) {
|
|
||||||
obj[configKey::userCountryCode] = userCountryCode;
|
|
||||||
}
|
|
||||||
if (!serverCountryCode.isEmpty()) {
|
|
||||||
obj[configKey::serverCountryCode] = serverCountryCode;
|
|
||||||
}
|
|
||||||
if (!serviceType.isEmpty()) {
|
|
||||||
obj[configKey::serviceType] = serviceType;
|
|
||||||
}
|
|
||||||
if (!serviceProtocol.isEmpty()) {
|
|
||||||
obj[configKey::serviceProtocol] = serviceProtocol;
|
|
||||||
}
|
|
||||||
if (!authData.isEmpty()) {
|
|
||||||
obj[configKey::authData] = authData;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ProtocolData generateProtocolData(const QString &protocol)
|
|
||||||
{
|
|
||||||
ProtocolData protocolData;
|
|
||||||
if (protocol == configKey::cloak) {
|
|
||||||
protocolData.certRequest = OpenVpnConfigurator::createCertRequest();
|
|
||||||
} else if (protocol == configKey::awg) {
|
|
||||||
auto connData = WireguardConfigurator::genClientKeys();
|
|
||||||
protocolData.wireGuardClientPubKey = connData.clientPubKey;
|
|
||||||
protocolData.wireGuardClientPrivKey = connData.clientPrivKey;
|
|
||||||
} else if (protocol == configKey::vless) {
|
|
||||||
protocolData.xrayUuid = QUuid::createUuid().toString(QUuid::WithoutBraces);
|
|
||||||
}
|
|
||||||
|
|
||||||
return protocolData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void appendProtocolDataToApiPayload(const QString &protocol, const ProtocolData &protocolData, QJsonObject &apiPayload)
|
|
||||||
{
|
|
||||||
if (protocol == configKey::cloak) {
|
|
||||||
apiPayload[configKey::certificate] = protocolData.certRequest.request;
|
|
||||||
} else if (protocol == configKey::awg) {
|
|
||||||
apiPayload[configKey::publicKey] = protocolData.wireGuardClientPubKey;
|
|
||||||
} else if (protocol == configKey::vless) {
|
|
||||||
apiPayload[configKey::publicKey] = protocolData.xrayUuid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode fillServerConfig(const QString &protocol, const ProtocolData &apiPayloadData, const QByteArray &apiResponseBody,
|
|
||||||
QJsonObject &serverConfig)
|
|
||||||
{
|
|
||||||
QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString();
|
|
||||||
|
|
||||||
data.replace("vpn://", "");
|
|
||||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
|
||||||
|
|
||||||
if (ba.isEmpty()) {
|
|
||||||
qDebug() << "empty vpn key";
|
|
||||||
return ErrorCode::ApiConfigEmptyError;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray ba_uncompressed = qUncompress(ba);
|
|
||||||
if (!ba_uncompressed.isEmpty()) {
|
|
||||||
ba = ba_uncompressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString configStr = ba;
|
|
||||||
if (protocol == configKey::cloak) {
|
|
||||||
configStr.replace("<key>", "<key>\n");
|
|
||||||
configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
|
|
||||||
} else if (protocol == configKey::awg) {
|
|
||||||
configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
|
||||||
auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
|
||||||
auto containers = newServerConfig.value(config_key::containers).toArray();
|
|
||||||
if (containers.isEmpty()) {
|
|
||||||
qDebug() << "missing containers field";
|
|
||||||
return ErrorCode::ApiConfigEmptyError;
|
|
||||||
}
|
|
||||||
auto container = containers.at(0).toObject();
|
|
||||||
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg);
|
|
||||||
auto serverProtocolConfig = container.value(containerName).toObject();
|
|
||||||
auto clientProtocolConfig =
|
|
||||||
QJsonDocument::fromJson(serverProtocolConfig.value(config_key::last_config).toString().toUtf8()).object();
|
|
||||||
|
|
||||||
//TODO looks like this block can be removed after v1 configs EOL
|
|
||||||
|
|
||||||
serverProtocolConfig[config_key::junkPacketCount] = clientProtocolConfig.value(config_key::junkPacketCount);
|
|
||||||
serverProtocolConfig[config_key::junkPacketMinSize] = clientProtocolConfig.value(config_key::junkPacketMinSize);
|
|
||||||
serverProtocolConfig[config_key::junkPacketMaxSize] = clientProtocolConfig.value(config_key::junkPacketMaxSize);
|
|
||||||
serverProtocolConfig[config_key::initPacketJunkSize] = clientProtocolConfig.value(config_key::initPacketJunkSize);
|
|
||||||
serverProtocolConfig[config_key::responsePacketJunkSize] = clientProtocolConfig.value(config_key::responsePacketJunkSize);
|
|
||||||
serverProtocolConfig[config_key::initPacketMagicHeader] = clientProtocolConfig.value(config_key::initPacketMagicHeader);
|
|
||||||
serverProtocolConfig[config_key::responsePacketMagicHeader] = clientProtocolConfig.value(config_key::responsePacketMagicHeader);
|
|
||||||
serverProtocolConfig[config_key::underloadPacketMagicHeader] = clientProtocolConfig.value(config_key::underloadPacketMagicHeader);
|
|
||||||
serverProtocolConfig[config_key::transportPacketMagicHeader] = clientProtocolConfig.value(config_key::transportPacketMagicHeader);
|
|
||||||
|
|
||||||
serverProtocolConfig[config_key::cookieReplyPacketJunkSize] = clientProtocolConfig.value(config_key::cookieReplyPacketJunkSize);
|
|
||||||
serverProtocolConfig[config_key::transportPacketJunkSize] = clientProtocolConfig.value(config_key::transportPacketJunkSize);
|
|
||||||
serverProtocolConfig[config_key::specialJunk1] = clientProtocolConfig.value(config_key::specialJunk1);
|
|
||||||
serverProtocolConfig[config_key::specialJunk2] = clientProtocolConfig.value(config_key::specialJunk2);
|
|
||||||
serverProtocolConfig[config_key::specialJunk3] = clientProtocolConfig.value(config_key::specialJunk3);
|
|
||||||
serverProtocolConfig[config_key::specialJunk4] = clientProtocolConfig.value(config_key::specialJunk4);
|
|
||||||
serverProtocolConfig[config_key::specialJunk5] = clientProtocolConfig.value(config_key::specialJunk5);
|
|
||||||
serverProtocolConfig[config_key::controlledJunk1] = clientProtocolConfig.value(config_key::controlledJunk1);
|
|
||||||
serverProtocolConfig[config_key::controlledJunk2] = clientProtocolConfig.value(config_key::controlledJunk2);
|
|
||||||
serverProtocolConfig[config_key::controlledJunk3] = clientProtocolConfig.value(config_key::controlledJunk3);
|
|
||||||
serverProtocolConfig[config_key::specialHandshakeTimeout] = clientProtocolConfig.value(config_key::specialHandshakeTimeout);
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
container[containerName] = serverProtocolConfig;
|
|
||||||
containers.replace(0, container);
|
|
||||||
newServerConfig[config_key::containers] = containers;
|
|
||||||
configStr = QString(QJsonDocument(newServerConfig).toJson());
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
|
||||||
serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1);
|
|
||||||
serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2);
|
|
||||||
serverConfig[config_key::containers] = newServerConfig.value(config_key::containers);
|
|
||||||
serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName);
|
|
||||||
|
|
||||||
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
|
||||||
serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion);
|
|
||||||
serverConfig[config_key::description] = newServerConfig.value(config_key::description);
|
|
||||||
serverConfig[config_key::name] = newServerConfig.value(config_key::name);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto defaultContainer = newServerConfig.value(config_key::defaultContainer).toString();
|
|
||||||
serverConfig[config_key::defaultContainer] = defaultContainer;
|
|
||||||
|
|
||||||
QVariantMap map = serverConfig.value(configKey::apiConfig).toObject().toVariantMap();
|
|
||||||
map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap());
|
|
||||||
auto apiConfig = QJsonObject::fromVariantMap(map);
|
|
||||||
|
|
||||||
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
|
||||||
apiConfig.insert(apiDefs::key::supportedProtocols,
|
|
||||||
QJsonDocument::fromJson(apiResponseBody).object().value(apiDefs::key::supportedProtocols).toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
serverConfig[configKey::apiConfig] = apiConfig;
|
|
||||||
|
|
||||||
return ErrorCode::NoError;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel,
|
ApiConfigsController::ApiConfigsController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
|
|
@ -239,26 +63,22 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
|
||||||
QString(APP_VERSION),
|
|
||||||
m_settings->getInstallationUuid(true),
|
|
||||||
apiConfigObject.value(configKey::userCountryCode).toString(),
|
|
||||||
serverCountryCode,
|
|
||||||
apiConfigObject.value(configKey::serviceType).toString(),
|
|
||||||
m_apiServicesModel->getSelectedServiceProtocol(),
|
|
||||||
serverConfigObject.value(configKey::authData).toObject() };
|
|
||||||
|
|
||||||
QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString();
|
QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString();
|
||||||
ProtocolData protocolData = generateProtocolData(protocol);
|
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
||||||
|
|
||||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||||
appendProtocolDataToApiPayload(gatewayRequestData.serviceProtocol, protocolData, apiPayload);
|
apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode);
|
||||||
|
apiPayload[configKey::serverCountryCode] = serverCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
|
||||||
|
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/native_config"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/native_config"), apiPayload, responseBody);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
emit errorOccurred(errorCode);
|
emit errorOccurred(errorCode);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -266,7 +86,7 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode,
|
||||||
|
|
||||||
QJsonObject jsonConfig = QJsonDocument::fromJson(responseBody).object();
|
QJsonObject jsonConfig = QJsonDocument::fromJson(responseBody).object();
|
||||||
QString nativeConfig = jsonConfig.value(configKey::config).toString();
|
QString nativeConfig = jsonConfig.value(configKey::config).toString();
|
||||||
nativeConfig.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", protocolData.wireGuardClientPrivKey);
|
nativeConfig.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
||||||
|
|
||||||
SystemController::saveFile(fileName, nativeConfig);
|
SystemController::saveFile(fileName, nativeConfig);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -274,22 +94,22 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode,
|
||||||
|
|
||||||
bool ApiConfigsController::revokeNativeConfig(const QString &serverCountryCode)
|
bool ApiConfigsController::revokeNativeConfig(const QString &serverCountryCode)
|
||||||
{
|
{
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
auto serverConfigObject = m_serversModel->getServerConfig(m_serversModel->getProcessedServerIndex());
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString();
|
||||||
QString(APP_VERSION),
|
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
||||||
m_settings->getInstallationUuid(true),
|
|
||||||
apiConfigObject.value(configKey::userCountryCode).toString(),
|
|
||||||
serverCountryCode,
|
|
||||||
apiConfigObject.value(configKey::serviceType).toString(),
|
|
||||||
m_apiServicesModel->getSelectedServiceProtocol(),
|
|
||||||
serverConfigObject.value(configKey::authData).toObject() };
|
|
||||||
|
|
||||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode);
|
||||||
|
apiPayload[configKey::serverCountryCode] = serverCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
|
||||||
|
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/revoke_native_config"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_native_config"), apiPayload, responseBody);
|
||||||
if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) {
|
if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) {
|
||||||
emit errorOccurred(errorCode);
|
emit errorOccurred(errorCode);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -320,11 +140,13 @@ void ApiConfigsController::copyVpnKeyToClipboard()
|
||||||
|
|
||||||
bool ApiConfigsController::fillAvailableServices()
|
bool ApiConfigsController::fillAvailableServices()
|
||||||
{
|
{
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
QJsonObject apiPayload;
|
QJsonObject apiPayload;
|
||||||
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/services"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/services"), apiPayload, responseBody);
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
if (!responseBody.contains("services")) {
|
if (!responseBody.contains("services")) {
|
||||||
errorCode = ErrorCode::ApiServicesMissingError;
|
errorCode = ErrorCode::ApiServicesMissingError;
|
||||||
|
|
@ -343,36 +165,32 @@ bool ApiConfigsController::fillAvailableServices()
|
||||||
|
|
||||||
bool ApiConfigsController::importServiceFromGateway()
|
bool ApiConfigsController::importServiceFromGateway()
|
||||||
{
|
{
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
if (m_serversModel->isServerFromApiAlreadyExists(m_apiServicesModel->getCountryCode(), m_apiServicesModel->getSelectedServiceType(),
|
||||||
QString(APP_VERSION),
|
m_apiServicesModel->getSelectedServiceProtocol())) {
|
||||||
m_settings->getInstallationUuid(true),
|
|
||||||
m_apiServicesModel->getCountryCode(),
|
|
||||||
"",
|
|
||||||
m_apiServicesModel->getSelectedServiceType(),
|
|
||||||
m_apiServicesModel->getSelectedServiceProtocol(),
|
|
||||||
QJsonObject() };
|
|
||||||
|
|
||||||
if (m_serversModel->isServerFromApiAlreadyExists(gatewayRequestData.userCountryCode, gatewayRequestData.serviceType,
|
|
||||||
gatewayRequestData.serviceProtocol)) {
|
|
||||||
emit errorOccurred(ErrorCode::ApiConfigAlreadyAdded);
|
emit errorOccurred(ErrorCode::ApiConfigAlreadyAdded);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolData protocolData = generateProtocolData(gatewayRequestData.serviceProtocol);
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
auto installationUuid = m_settings->getInstallationUuid(true);
|
||||||
appendProtocolDataToApiPayload(gatewayRequestData.serviceProtocol, protocolData, apiPayload);
|
auto userCountryCode = m_apiServicesModel->getCountryCode();
|
||||||
|
auto serviceType = m_apiServicesModel->getSelectedServiceType();
|
||||||
|
auto serviceProtocol = m_apiServicesModel->getSelectedServiceProtocol();
|
||||||
|
|
||||||
|
ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol);
|
||||||
|
|
||||||
|
QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::userCountryCode] = userCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = serviceType;
|
||||||
|
apiPayload[configKey::uuid] = installationUuid;
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody);
|
||||||
|
|
||||||
QJsonObject serverConfig;
|
QJsonObject serverConfig;
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
errorCode = fillServerConfig(gatewayRequestData.serviceProtocol, protocolData, responseBody, serverConfig);
|
fillServerConfig(serviceProtocol, apiPayloadData, responseBody, serverConfig);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit errorOccurred(errorCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
QJsonObject apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||||
apiConfig.insert(configKey::userCountryCode, m_apiServicesModel->getCountryCode());
|
apiConfig.insert(configKey::userCountryCode, m_apiServicesModel->getCountryCode());
|
||||||
|
|
@ -393,33 +211,37 @@ bool ApiConfigsController::importServiceFromGateway()
|
||||||
bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const QString &newCountryCode, const QString &newCountryName,
|
||||||
bool reloadServiceConfig)
|
bool reloadServiceConfig)
|
||||||
{
|
{
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
auto apiConfig = serverConfig.value(configKey::apiConfig).toObject();
|
||||||
|
auto authData = serverConfig.value(configKey::authData).toObject();
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
auto installationUuid = m_settings->getInstallationUuid(true);
|
||||||
QString(APP_VERSION),
|
auto userCountryCode = apiConfig.value(configKey::userCountryCode).toString();
|
||||||
m_settings->getInstallationUuid(true),
|
auto serviceType = apiConfig.value(configKey::serviceType).toString();
|
||||||
apiConfig.value(configKey::userCountryCode).toString(),
|
auto serviceProtocol = apiConfig.value(configKey::serviceProtocol).toString();
|
||||||
newCountryCode,
|
|
||||||
apiConfig.value(configKey::serviceType).toString(),
|
|
||||||
apiConfig.value(configKey::serviceProtocol).toString(),
|
|
||||||
serverConfig.value(configKey::authData).toObject() };
|
|
||||||
|
|
||||||
ProtocolData protocolData = generateProtocolData(gatewayRequestData.serviceProtocol);
|
ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol);
|
||||||
|
|
||||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData);
|
||||||
appendProtocolDataToApiPayload(gatewayRequestData.serviceProtocol, protocolData, apiPayload);
|
apiPayload[configKey::userCountryCode] = userCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = serviceType;
|
||||||
|
apiPayload[configKey::uuid] = installationUuid;
|
||||||
|
|
||||||
|
if (!newCountryCode.isEmpty()) {
|
||||||
|
apiPayload[configKey::serverCountryCode] = newCountryCode;
|
||||||
|
}
|
||||||
|
if (!authData.isEmpty()) {
|
||||||
|
apiPayload[configKey::authData] = authData;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/config"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/config"), apiPayload, responseBody);
|
||||||
|
|
||||||
QJsonObject newServerConfig;
|
QJsonObject newServerConfig;
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
errorCode = fillServerConfig(gatewayRequestData.serviceProtocol, protocolData, responseBody, newServerConfig);
|
fillServerConfig(serviceProtocol, apiPayloadData, responseBody, newServerConfig);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit errorOccurred(errorCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject();
|
QJsonObject newApiConfig = newServerConfig.value(configKey::apiConfig).toObject();
|
||||||
newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode));
|
newApiConfig.insert(configKey::userCountryCode, apiConfig.value(configKey::userCountryCode));
|
||||||
|
|
@ -428,12 +250,8 @@ bool ApiConfigsController::updateServiceFromGateway(const int serverIndex, const
|
||||||
newApiConfig.insert(apiDefs::key::vpnKey, apiConfig.value(apiDefs::key::vpnKey));
|
newApiConfig.insert(apiDefs::key::vpnKey, apiConfig.value(apiDefs::key::vpnKey));
|
||||||
|
|
||||||
newServerConfig.insert(configKey::apiConfig, newApiConfig);
|
newServerConfig.insert(configKey::apiConfig, newApiConfig);
|
||||||
newServerConfig.insert(configKey::authData, gatewayRequestData.authData);
|
newServerConfig.insert(configKey::authData, authData);
|
||||||
|
|
||||||
if (serverConfig.value(config_key::nameOverriddenByUser).toBool()) {
|
|
||||||
newServerConfig.insert(config_key::name, serverConfig.value(config_key::name));
|
|
||||||
newServerConfig.insert(config_key::nameOverriddenByUser, true);
|
|
||||||
}
|
|
||||||
m_serversModel->editServer(newServerConfig, serverIndex);
|
m_serversModel->editServer(newServerConfig, serverIndex);
|
||||||
if (reloadServiceConfig) {
|
if (reloadServiceConfig) {
|
||||||
emit reloadServerFromApiFinished(tr("API config reloaded"));
|
emit reloadServerFromApiFinished(tr("API config reloaded"));
|
||||||
|
|
@ -456,20 +274,16 @@ bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex)
|
||||||
QThread::msleep(10);
|
QThread::msleep(10);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
m_settings->isStrictKillSwitchEnabled());
|
|
||||||
|
|
||||||
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
auto serverConfig = m_serversModel->getServerConfig(serverIndex);
|
||||||
auto installationUuid = m_settings->getInstallationUuid(true);
|
auto installationUuid = m_settings->getInstallationUuid(true);
|
||||||
|
|
||||||
QString serviceProtocol = serverConfig.value(configKey::protocol).toString();
|
QString serviceProtocol = serverConfig.value(configKey::protocol).toString();
|
||||||
ProtocolData protocolData = generateProtocolData(serviceProtocol);
|
ApiPayloadData apiPayloadData = generateApiPayloadData(serviceProtocol);
|
||||||
|
|
||||||
QJsonObject apiPayload;
|
QJsonObject apiPayload = fillApiPayload(serviceProtocol, apiPayloadData);
|
||||||
appendProtocolDataToApiPayload(serviceProtocol, protocolData, apiPayload);
|
|
||||||
apiPayload[configKey::uuid] = installationUuid;
|
apiPayload[configKey::uuid] = installationUuid;
|
||||||
apiPayload[configKey::osVersion] = QSysInfo::productType();
|
|
||||||
apiPayload[configKey::appVersion] = QString(APP_VERSION);
|
|
||||||
apiPayload[configKey::accessToken] = serverConfig.value(configKey::accessToken).toString();
|
apiPayload[configKey::accessToken] = serverConfig.value(configKey::accessToken).toString();
|
||||||
apiPayload[configKey::apiEndpoint] = serverConfig.value(configKey::apiEndpoint).toString();
|
apiPayload[configKey::apiEndpoint] = serverConfig.value(configKey::apiEndpoint).toString();
|
||||||
|
|
||||||
|
|
@ -477,11 +291,7 @@ bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex)
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/proxy_config"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/proxy_config"), apiPayload, responseBody);
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
if (errorCode == ErrorCode::NoError) {
|
||||||
errorCode = fillServerConfig(serviceProtocol, protocolData, responseBody, serverConfig);
|
fillServerConfig(serviceProtocol, apiPayloadData, responseBody, serverConfig);
|
||||||
if (errorCode != ErrorCode::NoError) {
|
|
||||||
emit errorOccurred(errorCode);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_serversModel->editServer(serverConfig, serverIndex);
|
m_serversModel->editServer(serverConfig, serverIndex);
|
||||||
emit updateServerFromApiFinished();
|
emit updateServerFromApiFinished();
|
||||||
|
|
@ -494,6 +304,8 @@ bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex)
|
||||||
|
|
||||||
bool ApiConfigsController::deactivateDevice()
|
bool ApiConfigsController::deactivateDevice()
|
||||||
{
|
{
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
auto serverIndex = m_serversModel->getProcessedServerIndex();
|
auto serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
auto serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
auto serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
||||||
|
|
@ -502,19 +314,18 @@ bool ApiConfigsController::deactivateDevice()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString();
|
||||||
QString(APP_VERSION),
|
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
||||||
m_settings->getInstallationUuid(true),
|
|
||||||
apiConfigObject.value(configKey::userCountryCode).toString(),
|
|
||||||
apiConfigObject.value(configKey::serverCountryCode).toString(),
|
|
||||||
apiConfigObject.value(configKey::serviceType).toString(),
|
|
||||||
"",
|
|
||||||
serverConfigObject.value(configKey::authData).toObject() };
|
|
||||||
|
|
||||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode);
|
||||||
|
apiPayload[configKey::serverCountryCode] = apiConfigObject.value(configKey::serverCountryCode);
|
||||||
|
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
|
||||||
|
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
|
||||||
|
apiPayload[configKey::uuid] = m_settings->getInstallationUuid(true);
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/revoke_config"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody);
|
||||||
if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) {
|
if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) {
|
||||||
emit errorOccurred(errorCode);
|
emit errorOccurred(errorCode);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -528,6 +339,8 @@ bool ApiConfigsController::deactivateDevice()
|
||||||
|
|
||||||
bool ApiConfigsController::deactivateExternalDevice(const QString &uuid, const QString &serverCountryCode)
|
bool ApiConfigsController::deactivateExternalDevice(const QString &uuid, const QString &serverCountryCode)
|
||||||
{
|
{
|
||||||
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
|
||||||
|
|
||||||
auto serverIndex = m_serversModel->getProcessedServerIndex();
|
auto serverIndex = m_serversModel->getProcessedServerIndex();
|
||||||
auto serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
auto serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
||||||
|
|
@ -536,19 +349,18 @@ bool ApiConfigsController::deactivateExternalDevice(const QString &uuid, const Q
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GatewayRequestData gatewayRequestData { QSysInfo::productType(),
|
QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString();
|
||||||
QString(APP_VERSION),
|
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
||||||
uuid,
|
|
||||||
apiConfigObject.value(configKey::userCountryCode).toString(),
|
|
||||||
serverCountryCode,
|
|
||||||
apiConfigObject.value(configKey::serviceType).toString(),
|
|
||||||
"",
|
|
||||||
serverConfigObject.value(configKey::authData).toObject() };
|
|
||||||
|
|
||||||
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
|
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||||
|
apiPayload[configKey::userCountryCode] = apiConfigObject.value(configKey::userCountryCode);
|
||||||
|
apiPayload[configKey::serverCountryCode] = serverCountryCode;
|
||||||
|
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
|
||||||
|
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
|
||||||
|
apiPayload[configKey::uuid] = uuid;
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
ErrorCode errorCode = executeRequest(QString("%1v1/revoke_config"), apiPayload, responseBody);
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/revoke_config"), apiPayload, responseBody);
|
||||||
if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) {
|
if (errorCode != ErrorCode::NoError && errorCode != ErrorCode::ApiNotFoundError) {
|
||||||
emit errorOccurred(errorCode);
|
emit errorOccurred(errorCode);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -587,29 +399,108 @@ bool ApiConfigsController::isConfigValid()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiConfigsController::setCurrentProtocol(const QString &protocolName)
|
ApiConfigsController::ApiPayloadData ApiConfigsController::generateApiPayloadData(const QString &protocol)
|
||||||
{
|
{
|
||||||
auto serverIndex = m_serversModel->getProcessedServerIndex();
|
ApiConfigsController::ApiPayloadData apiPayload;
|
||||||
auto serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
if (protocol == configKey::cloak) {
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
apiPayload.certRequest = OpenVpnConfigurator::createCertRequest();
|
||||||
|
} else if (protocol == configKey::awg) {
|
||||||
apiConfigObject[configKey::serviceProtocol] = protocolName;
|
auto connData = WireguardConfigurator::genClientKeys();
|
||||||
|
apiPayload.wireGuardClientPubKey = connData.clientPubKey;
|
||||||
serverConfigObject.insert(configKey::apiConfig, apiConfigObject);
|
apiPayload.wireGuardClientPrivKey = connData.clientPrivKey;
|
||||||
|
}
|
||||||
m_serversModel->editServer(serverConfigObject, serverIndex);
|
return apiPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ApiConfigsController::isVlessProtocol()
|
QJsonObject ApiConfigsController::fillApiPayload(const QString &protocol, const ApiPayloadData &apiPayloadData)
|
||||||
{
|
{
|
||||||
auto serverIndex = m_serversModel->getProcessedServerIndex();
|
QJsonObject obj;
|
||||||
auto serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
if (protocol == configKey::cloak) {
|
||||||
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
|
obj[configKey::certificate] = apiPayloadData.certRequest.request;
|
||||||
|
} else if (protocol == configKey::awg) {
|
||||||
if (apiConfigObject[configKey::serviceProtocol].toString() == "vless") {
|
obj[configKey::publicKey] = apiPayloadData.wireGuardClientPubKey;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
obj[configKey::osVersion] = QSysInfo::productType();
|
||||||
|
obj[configKey::appVersion] = QString(APP_VERSION);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiConfigsController::fillServerConfig(const QString &protocol, const ApiPayloadData &apiPayloadData,
|
||||||
|
const QByteArray &apiResponseBody, QJsonObject &serverConfig)
|
||||||
|
{
|
||||||
|
QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString();
|
||||||
|
|
||||||
|
data.replace("vpn://", "");
|
||||||
|
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
|
|
||||||
|
if (ba.isEmpty()) {
|
||||||
|
emit errorOccurred(ErrorCode::ApiConfigEmptyError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray ba_uncompressed = qUncompress(ba);
|
||||||
|
if (!ba_uncompressed.isEmpty()) {
|
||||||
|
ba = ba_uncompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString configStr = ba;
|
||||||
|
if (protocol == configKey::cloak) {
|
||||||
|
configStr.replace("<key>", "<key>\n");
|
||||||
|
configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
|
||||||
|
} else if (protocol == configKey::awg) {
|
||||||
|
configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
||||||
|
auto newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||||
|
auto containers = newServerConfig.value(config_key::containers).toArray();
|
||||||
|
if (containers.isEmpty()) {
|
||||||
|
return; // todo process error
|
||||||
|
}
|
||||||
|
auto container = containers.at(0).toObject();
|
||||||
|
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg);
|
||||||
|
auto containerConfig = container.value(containerName).toObject();
|
||||||
|
auto protocolConfig = QJsonDocument::fromJson(containerConfig.value(config_key::last_config).toString().toUtf8()).object();
|
||||||
|
containerConfig[config_key::junkPacketCount] = protocolConfig.value(config_key::junkPacketCount);
|
||||||
|
containerConfig[config_key::junkPacketMinSize] = protocolConfig.value(config_key::junkPacketMinSize);
|
||||||
|
containerConfig[config_key::junkPacketMaxSize] = protocolConfig.value(config_key::junkPacketMaxSize);
|
||||||
|
containerConfig[config_key::initPacketJunkSize] = protocolConfig.value(config_key::initPacketJunkSize);
|
||||||
|
containerConfig[config_key::responsePacketJunkSize] = protocolConfig.value(config_key::responsePacketJunkSize);
|
||||||
|
containerConfig[config_key::initPacketMagicHeader] = protocolConfig.value(config_key::initPacketMagicHeader);
|
||||||
|
containerConfig[config_key::responsePacketMagicHeader] = protocolConfig.value(config_key::responsePacketMagicHeader);
|
||||||
|
containerConfig[config_key::underloadPacketMagicHeader] = protocolConfig.value(config_key::underloadPacketMagicHeader);
|
||||||
|
containerConfig[config_key::transportPacketMagicHeader] = protocolConfig.value(config_key::transportPacketMagicHeader);
|
||||||
|
container[containerName] = containerConfig;
|
||||||
|
containers.replace(0, container);
|
||||||
|
newServerConfig[config_key::containers] = containers;
|
||||||
|
configStr = QString(QJsonDocument(newServerConfig).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject newServerConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||||
|
serverConfig[config_key::dns1] = newServerConfig.value(config_key::dns1);
|
||||||
|
serverConfig[config_key::dns2] = newServerConfig.value(config_key::dns2);
|
||||||
|
serverConfig[config_key::containers] = newServerConfig.value(config_key::containers);
|
||||||
|
serverConfig[config_key::hostName] = newServerConfig.value(config_key::hostName);
|
||||||
|
|
||||||
|
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
||||||
|
serverConfig[config_key::configVersion] = newServerConfig.value(config_key::configVersion);
|
||||||
|
serverConfig[config_key::description] = newServerConfig.value(config_key::description);
|
||||||
|
serverConfig[config_key::name] = newServerConfig.value(config_key::name);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto defaultContainer = newServerConfig.value(config_key::defaultContainer).toString();
|
||||||
|
serverConfig[config_key::defaultContainer] = defaultContainer;
|
||||||
|
|
||||||
|
QVariantMap map = serverConfig.value(configKey::apiConfig).toObject().toVariantMap();
|
||||||
|
map.insert(newServerConfig.value(configKey::apiConfig).toObject().toVariantMap());
|
||||||
|
auto apiConfig = QJsonObject::fromVariantMap(map);
|
||||||
|
|
||||||
|
if (newServerConfig.value(config_key::configVersion).toInt() == apiDefs::ConfigSource::AmneziaGateway) {
|
||||||
|
apiConfig.insert(configKey::serviceInfo, QJsonDocument::fromJson(apiResponseBody).object().value(configKey::serviceInfo).toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
serverConfig[configKey::apiConfig] = apiConfig;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QString> ApiConfigsController::getQrCodes()
|
QList<QString> ApiConfigsController::getQrCodes()
|
||||||
|
|
@ -626,10 +517,3 @@ QString ApiConfigsController::getVpnKey()
|
||||||
{
|
{
|
||||||
return m_vpnKey;
|
return m_vpnKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ApiConfigsController::executeRequest(const QString &endpoint, const QJsonObject &apiPayload, QByteArray &responseBody)
|
|
||||||
{
|
|
||||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
|
||||||
m_settings->isStrictKillSwitchEnabled());
|
|
||||||
return gatewayController.post(endpoint, apiPayload, responseBody);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,6 @@ public slots:
|
||||||
|
|
||||||
bool isConfigValid();
|
bool isConfigValid();
|
||||||
|
|
||||||
void setCurrentProtocol(const QString &protocolName);
|
|
||||||
bool isVlessProtocol();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void errorOccurred(ErrorCode errorCode);
|
void errorOccurred(ErrorCode errorCode);
|
||||||
|
|
||||||
|
|
@ -49,12 +46,23 @@ signals:
|
||||||
void vpnKeyExportReady();
|
void vpnKeyExportReady();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct ApiPayloadData
|
||||||
|
{
|
||||||
|
OpenVpnConfigurator::ConnectionData certRequest;
|
||||||
|
|
||||||
|
QString wireGuardClientPrivKey;
|
||||||
|
QString wireGuardClientPubKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
||||||
|
QJsonObject fillApiPayload(const QString &protocol, const ApiPayloadData &apiPayloadData);
|
||||||
|
void fillServerConfig(const QString &protocol, const ApiPayloadData &apiPayloadData, const QByteArray &apiResponseBody,
|
||||||
|
QJsonObject &serverConfig);
|
||||||
|
|
||||||
QList<QString> getQrCodes();
|
QList<QString> getQrCodes();
|
||||||
int getQrCodesCount();
|
int getQrCodesCount();
|
||||||
QString getVpnKey();
|
QString getVpnKey();
|
||||||
|
|
||||||
ErrorCode executeRequest(const QString &endpoint, const QJsonObject &apiPayload, QByteArray &responseBody);
|
|
||||||
|
|
||||||
QList<QString> m_qrCodes;
|
QList<QString> m_qrCodes;
|
||||||
QString m_vpnKey;
|
QString m_vpnKey;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
#include "apiPremV1MigrationController.h"
|
|
||||||
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include "core/api/apiDefs.h"
|
|
||||||
#include "core/api/apiUtils.h"
|
|
||||||
#include "core/controllers/gatewayController.h"
|
|
||||||
|
|
||||||
ApiPremV1MigrationController::ApiPremV1MigrationController(const QSharedPointer<ServersModel> &serversModel,
|
|
||||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
|
||||||
: QObject(parent), m_serversModel(serversModel), m_settings(settings)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApiPremV1MigrationController::hasConfigsToMigration()
|
|
||||||
{
|
|
||||||
QJsonArray vpnKeys;
|
|
||||||
|
|
||||||
auto serversCount = m_serversModel->getServersCount();
|
|
||||||
for (size_t i = 0; i < serversCount; i++) {
|
|
||||||
auto serverConfigObject = m_serversModel->getServerConfig(i);
|
|
||||||
|
|
||||||
if (apiUtils::getConfigType(serverConfigObject) != apiDefs::ConfigType::AmneziaPremiumV1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString vpnKey = apiUtils::getPremiumV1VpnKey(serverConfigObject);
|
|
||||||
vpnKeys.append(vpnKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vpnKeys.isEmpty()) {
|
|
||||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
|
||||||
m_settings->isStrictKillSwitchEnabled());
|
|
||||||
QJsonObject apiPayload;
|
|
||||||
|
|
||||||
apiPayload["configs"] = vpnKeys;
|
|
||||||
QByteArray responseBody;
|
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/is-active-subscription"), apiPayload, responseBody);
|
|
||||||
|
|
||||||
auto migrationsStatus = QJsonDocument::fromJson(responseBody).object();
|
|
||||||
for (const auto &migrationStatus : migrationsStatus) {
|
|
||||||
if (migrationStatus == "not_found") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApiPremV1MigrationController::getSubscriptionList(const QString &email)
|
|
||||||
{
|
|
||||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
|
||||||
m_settings->isStrictKillSwitchEnabled());
|
|
||||||
QJsonObject apiPayload;
|
|
||||||
|
|
||||||
apiPayload[apiDefs::key::email] = email;
|
|
||||||
QByteArray responseBody;
|
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/subscription-list"), apiPayload, responseBody);
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
m_email = email;
|
|
||||||
m_subscriptionsModel = QJsonDocument::fromJson(responseBody).array();
|
|
||||||
if (m_subscriptionsModel.isEmpty()) {
|
|
||||||
emit noSubscriptionToMigrate();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit subscriptionsModelChanged();
|
|
||||||
} else {
|
|
||||||
emit errorOccurred(ErrorCode::ApiMigrationError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonArray ApiPremV1MigrationController::getSubscriptionModel()
|
|
||||||
{
|
|
||||||
return m_subscriptionsModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApiPremV1MigrationController::sendMigrationCode(const int subscriptionIndex)
|
|
||||||
{
|
|
||||||
QEventLoop wait;
|
|
||||||
QTimer::singleShot(1000, &wait, &QEventLoop::quit);
|
|
||||||
wait.exec();
|
|
||||||
|
|
||||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
|
||||||
m_settings->isStrictKillSwitchEnabled());
|
|
||||||
QJsonObject apiPayload;
|
|
||||||
|
|
||||||
apiPayload[apiDefs::key::email] = m_email;
|
|
||||||
QByteArray responseBody;
|
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/migration-code"), apiPayload, responseBody);
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
m_subscriptionIndex = subscriptionIndex;
|
|
||||||
emit otpSuccessfullySent();
|
|
||||||
} else {
|
|
||||||
emit errorOccurred(ErrorCode::ApiMigrationError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApiPremV1MigrationController::migrate(const QString &migrationCode)
|
|
||||||
{
|
|
||||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs,
|
|
||||||
m_settings->isStrictKillSwitchEnabled());
|
|
||||||
QJsonObject apiPayload;
|
|
||||||
|
|
||||||
apiPayload[apiDefs::key::email] = m_email;
|
|
||||||
apiPayload[apiDefs::key::orderId] = m_subscriptionsModel.at(m_subscriptionIndex).toObject().value(apiDefs::key::id).toString();
|
|
||||||
apiPayload[apiDefs::key::migrationCode] = migrationCode;
|
|
||||||
QByteArray responseBody;
|
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/prem-v1/migrate"), apiPayload, responseBody);
|
|
||||||
|
|
||||||
if (errorCode == ErrorCode::NoError) {
|
|
||||||
auto responseObject = QJsonDocument::fromJson(responseBody).object();
|
|
||||||
QString premiumV2VpnKey = responseObject.value(apiDefs::key::config).toString();
|
|
||||||
|
|
||||||
emit importPremiumV2VpnKey(premiumV2VpnKey);
|
|
||||||
} else {
|
|
||||||
emit errorOccurred(ErrorCode::ApiMigrationError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApiPremV1MigrationController::isPremV1MigrationReminderActive()
|
|
||||||
{
|
|
||||||
return m_settings->isPremV1MigrationReminderActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ApiPremV1MigrationController::disablePremV1MigrationReminder()
|
|
||||||
{
|
|
||||||
m_settings->disablePremV1MigrationReminder();
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
#ifndef APIPREMV1MIGRATIONCONTROLLER_H
|
|
||||||
#define APIPREMV1MIGRATIONCONTROLLER_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
|
|
||||||
#include "ui/models/servers_model.h"
|
|
||||||
|
|
||||||
class ApiPremV1MigrationController : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
ApiPremV1MigrationController(const QSharedPointer<ServersModel> &serversModel, const std::shared_ptr<Settings> &settings,
|
|
||||||
QObject *parent = nullptr);
|
|
||||||
|
|
||||||
Q_PROPERTY(QJsonArray subscriptionsModel READ getSubscriptionModel NOTIFY subscriptionsModelChanged)
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
bool hasConfigsToMigration();
|
|
||||||
void getSubscriptionList(const QString &email);
|
|
||||||
QJsonArray getSubscriptionModel();
|
|
||||||
void sendMigrationCode(const int subscriptionIndex);
|
|
||||||
void migrate(const QString &migrationCode);
|
|
||||||
|
|
||||||
bool isPremV1MigrationReminderActive();
|
|
||||||
void disablePremV1MigrationReminder();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void subscriptionsModelChanged();
|
|
||||||
|
|
||||||
void otpSuccessfullySent();
|
|
||||||
|
|
||||||
void importPremiumV2VpnKey(const QString &vpnKey);
|
|
||||||
|
|
||||||
void errorOccurred(ErrorCode errorCode);
|
|
||||||
|
|
||||||
void showMigrationDrawer();
|
|
||||||
void migrationFinished();
|
|
||||||
|
|
||||||
void noSubscriptionToMigrate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
|
||||||
|
|
||||||
QJsonArray m_subscriptionsModel;
|
|
||||||
int m_subscriptionIndex;
|
|
||||||
QString m_email;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // APIPREMV1MIGRATIONCONTROLLER_H
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "core/api/apiUtils.h"
|
#include "core/api/apiUtils.h"
|
||||||
#include "core/controllers/gatewayController.h"
|
#include "core/controllers/gatewayController.h"
|
||||||
#include "version.h"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
@ -49,8 +48,7 @@ bool ApiSettingsController::getAccountInfo(bool reload)
|
||||||
wait.exec();
|
wait.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), requestTimeoutMsecs,
|
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), requestTimeoutMsecs);
|
||||||
m_settings->isStrictKillSwitchEnabled());
|
|
||||||
|
|
||||||
auto processedIndex = m_serversModel->getProcessedServerIndex();
|
auto processedIndex = m_serversModel->getProcessedServerIndex();
|
||||||
auto serverConfig = m_serversModel->getServerConfig(processedIndex);
|
auto serverConfig = m_serversModel->getServerConfig(processedIndex);
|
||||||
|
|
@ -61,14 +59,15 @@ bool ApiSettingsController::getAccountInfo(bool reload)
|
||||||
apiPayload[configKey::userCountryCode] = apiConfig.value(configKey::userCountryCode).toString();
|
apiPayload[configKey::userCountryCode] = apiConfig.value(configKey::userCountryCode).toString();
|
||||||
apiPayload[configKey::serviceType] = apiConfig.value(configKey::serviceType).toString();
|
apiPayload[configKey::serviceType] = apiConfig.value(configKey::serviceType).toString();
|
||||||
apiPayload[configKey::authData] = authData;
|
apiPayload[configKey::authData] = authData;
|
||||||
apiPayload[apiDefs::key::cliVersion] = QString(APP_VERSION);
|
|
||||||
|
|
||||||
QByteArray responseBody;
|
QByteArray responseBody;
|
||||||
|
|
||||||
ErrorCode errorCode = gatewayController.post(QString("%1v1/account_info"), apiPayload, responseBody);
|
if (apiUtils::isPremiumServer(serverConfig)) {
|
||||||
if (errorCode != ErrorCode::NoError) {
|
ErrorCode errorCode = gatewayController.post(QString("%1v1/account_info"), apiPayload, responseBody);
|
||||||
emit errorOccurred(errorCode);
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return false;
|
emit errorOccurred(errorCode);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject accountInfo = QJsonDocument::fromJson(responseBody).object();
|
QJsonObject accountInfo = QJsonDocument::fromJson(responseBody).object();
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +163,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,7 +183,7 @@ void ExportController::generateAwgConfig(const QString &clientName)
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
QStringList lines = nativeConfig.value(config_key::config).toString().replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ void ExportController::generateShadowSocksConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,7 +240,7 @@ void ExportController::generateCloakConfig()
|
||||||
nativeConfig.insert("ProxyMethod", "shadowsocks");
|
nativeConfig.insert("ProxyMethod", "shadowsocks");
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,7 +257,7 @@ void ExportController::generateXrayConfig(const QString &clientName)
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
QStringList lines = QString(QJsonDocument(nativeConfig).toJson()).replace("\r", "").split("\n");
|
||||||
for (const QString &line : std::as_const(lines)) {
|
for (const QString &line : lines) {
|
||||||
m_config.append(line + "\n");
|
m_config.append(line + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#include "core/qrCodeUtils.h"
|
#include "core/qrCodeUtils.h"
|
||||||
#include "core/serialization/serialization.h"
|
#include "core/serialization/serialization.h"
|
||||||
#include "protocols/protocols_defs.h"
|
|
||||||
#include "systemController.h"
|
#include "systemController.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
|
|
@ -287,19 +286,6 @@ void ImportController::processNativeWireGuardConfig()
|
||||||
clientProtocolConfig[config_key::underloadPacketMagicHeader] = "3";
|
clientProtocolConfig[config_key::underloadPacketMagicHeader] = "3";
|
||||||
clientProtocolConfig[config_key::transportPacketMagicHeader] = "4";
|
clientProtocolConfig[config_key::transportPacketMagicHeader] = "4";
|
||||||
|
|
||||||
// clientProtocolConfig[config_key::cookieReplyPacketJunkSize] = "0";
|
|
||||||
// clientProtocolConfig[config_key::transportPacketJunkSize] = "0";
|
|
||||||
|
|
||||||
// clientProtocolConfig[config_key::specialJunk1] = "";
|
|
||||||
// clientProtocolConfig[config_key::specialJunk2] = "";
|
|
||||||
// clientProtocolConfig[config_key::specialJunk3] = "";
|
|
||||||
// clientProtocolConfig[config_key::specialJunk4] = "";
|
|
||||||
// clientProtocolConfig[config_key::specialJunk5] = "";
|
|
||||||
// clientProtocolConfig[config_key::controlledJunk1] = "";
|
|
||||||
// clientProtocolConfig[config_key::controlledJunk2] = "";
|
|
||||||
// clientProtocolConfig[config_key::controlledJunk3] = "";
|
|
||||||
// clientProtocolConfig[config_key::specialHandshakeTimeout] = "0";
|
|
||||||
|
|
||||||
clientProtocolConfig[config_key::isObfuscationEnabled] = true;
|
clientProtocolConfig[config_key::isObfuscationEnabled] = true;
|
||||||
|
|
||||||
serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(clientProtocolConfig).toJson());
|
serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(clientProtocolConfig).toJson());
|
||||||
|
|
@ -452,33 +438,21 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
|
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
|
||||||
|
|
||||||
QString protocolName = "wireguard";
|
QString protocolName = "wireguard";
|
||||||
|
if (!configMap.value(config_key::junkPacketCount).isEmpty() && !configMap.value(config_key::junkPacketMinSize).isEmpty()
|
||||||
const QStringList requiredJunkFields = { config_key::junkPacketCount, config_key::junkPacketMinSize,
|
&& !configMap.value(config_key::junkPacketMaxSize).isEmpty() && !configMap.value(config_key::initPacketJunkSize).isEmpty()
|
||||||
config_key::junkPacketMaxSize, config_key::initPacketJunkSize,
|
&& !configMap.value(config_key::responsePacketJunkSize).isEmpty() && !configMap.value(config_key::initPacketMagicHeader).isEmpty()
|
||||||
config_key::responsePacketJunkSize, config_key::initPacketMagicHeader,
|
&& !configMap.value(config_key::responsePacketMagicHeader).isEmpty()
|
||||||
config_key::responsePacketMagicHeader, config_key::underloadPacketMagicHeader,
|
&& !configMap.value(config_key::underloadPacketMagicHeader).isEmpty()
|
||||||
config_key::transportPacketMagicHeader };
|
&& !configMap.value(config_key::transportPacketMagicHeader).isEmpty()) {
|
||||||
|
lastConfig[config_key::junkPacketCount] = configMap.value(config_key::junkPacketCount);
|
||||||
const QStringList optionalJunkFields = { // config_key::cookieReplyPacketJunkSize,
|
lastConfig[config_key::junkPacketMinSize] = configMap.value(config_key::junkPacketMinSize);
|
||||||
// config_key::transportPacketJunkSize,
|
lastConfig[config_key::junkPacketMaxSize] = configMap.value(config_key::junkPacketMaxSize);
|
||||||
config_key::specialJunk1, config_key::specialJunk2, config_key::specialJunk3,
|
lastConfig[config_key::initPacketJunkSize] = configMap.value(config_key::initPacketJunkSize);
|
||||||
config_key::specialJunk4, config_key::specialJunk5, config_key::controlledJunk1,
|
lastConfig[config_key::responsePacketJunkSize] = configMap.value(config_key::responsePacketJunkSize);
|
||||||
config_key::controlledJunk2, config_key::controlledJunk3, config_key::specialHandshakeTimeout
|
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);
|
||||||
bool hasAllRequiredFields = std::all_of(requiredJunkFields.begin(), requiredJunkFields.end(),
|
lastConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
|
||||||
[&configMap](const QString &field) { return !configMap.value(field).isEmpty(); });
|
|
||||||
if (hasAllRequiredFields) {
|
|
||||||
for (const QString &field : requiredJunkFields) {
|
|
||||||
lastConfig[field] = configMap.value(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const QString &field : optionalJunkFields) {
|
|
||||||
if (!configMap.value(field).isEmpty()) {
|
|
||||||
lastConfig[field] = configMap.value(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protocolName = "awg";
|
protocolName = "awg";
|
||||||
m_configType = ConfigTypes::Awg;
|
m_configType = ConfigTypes::Awg;
|
||||||
}
|
}
|
||||||
|
|
@ -691,27 +665,27 @@ void ImportController::checkForMaliciousStrings(const QJsonObject &serverConfig)
|
||||||
containerConfig[ProtocolProps::protoToString(Proto::OpenVpn)].toObject()[config_key::last_config].toString();
|
containerConfig[ProtocolProps::protoToString(Proto::OpenVpn)].toObject()[config_key::last_config].toString();
|
||||||
QString protocolConfigJson = QJsonDocument::fromJson(protocolConfig.toUtf8()).object()[config_key::config].toString();
|
QString protocolConfigJson = QJsonDocument::fromJson(protocolConfig.toUtf8()).object()[config_key::config].toString();
|
||||||
|
|
||||||
|
const QRegularExpression regExp { "(\\w+-\\w+|\\w+)" };
|
||||||
|
const size_t dangerousTagsMaxCount = 3;
|
||||||
|
|
||||||
// https://github.com/OpenVPN/openvpn/blob/master/doc/man-sections/script-options.rst
|
// https://github.com/OpenVPN/openvpn/blob/master/doc/man-sections/script-options.rst
|
||||||
QStringList dangerousTags {
|
QStringList dangerousTags {
|
||||||
"up", "tls-verify", "ipchange", "client-connect", "route-up", "route-pre-down", "client-disconnect", "down", "learn-address", "auth-user-pass-verify"
|
"up", "tls-verify", "ipchange", "client-connect", "route-up", "route-pre-down", "client-disconnect", "down", "learn-address", "auth-user-pass-verify"
|
||||||
};
|
};
|
||||||
|
|
||||||
QStringList maliciousStrings;
|
QStringList maliciousStrings;
|
||||||
QStringList lines = protocolConfigJson.split('\n', Qt::SkipEmptyParts);
|
QStringList lines = protocolConfigJson.replace("\r", "").split("\n");
|
||||||
|
for (const QString &l : lines) {
|
||||||
for (const QString &rawLine : lines) {
|
QRegularExpressionMatch match = regExp.match(l);
|
||||||
QString line = rawLine.trimmed();
|
if (dangerousTags.contains(match.captured(0))) {
|
||||||
|
maliciousStrings << l;
|
||||||
QString command = line.section(' ', 0, 0, QString::SectionSkipEmpty);
|
|
||||||
if (dangerousTags.contains(command, Qt::CaseInsensitive)) {
|
|
||||||
maliciousStrings << rawLine;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_maliciousWarningText = tr("This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious "
|
m_maliciousWarningText = tr("This configuration contains an OpenVPN setup. OpenVPN configurations can include malicious "
|
||||||
"scripts, so only add it if you fully trust the provider of this config. ");
|
"scripts, so only add it if you fully trust the provider of this config. ");
|
||||||
|
|
||||||
if (!maliciousStrings.isEmpty()) {
|
if (maliciousStrings.size() >= dangerousTagsMaxCount) {
|
||||||
m_maliciousWarningText.push_back(tr("<br>In the imported configuration, potentially dangerous lines were found:"));
|
m_maliciousWarningText.push_back(tr("<br>In the imported configuration, potentially dangerous lines were found:"));
|
||||||
for (const auto &string : maliciousStrings) {
|
for (const auto &string : maliciousStrings) {
|
||||||
m_maliciousWarningText.push_back(QString("<br><i>%1</i>").arg(string));
|
m_maliciousWarningText.push_back(QString("<br><i>%1</i>").arg(string));
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
|
|
||||||
#include "core/api/apiUtils.h"
|
|
||||||
#include "core/controllers/serverController.h"
|
#include "core/controllers/serverController.h"
|
||||||
#include "core/controllers/vpnConfigurationController.h"
|
#include "core/controllers/vpnConfigurationController.h"
|
||||||
#include "core/networkUtilities.h"
|
#include "core/networkUtilities.h"
|
||||||
|
|
@ -16,6 +15,7 @@
|
||||||
#include "ui/models/protocols/awgConfigModel.h"
|
#include "ui/models/protocols/awgConfigModel.h"
|
||||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
#include "core/api/apiUtils.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
@ -79,36 +79,12 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||||
|
|
||||||
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
||||||
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
||||||
// int s3 = QRandomGenerator::global()->bounded(15, 150);
|
while (s1 + AwgConstant::messageInitiationSize == s2 + AwgConstant::messageResponseSize) {
|
||||||
// int s4 = QRandomGenerator::global()->bounded(15, 150);
|
|
||||||
|
|
||||||
// Ensure all values are unique and don't create equal packet sizes
|
|
||||||
QSet<int> usedValues;
|
|
||||||
usedValues.insert(s1);
|
|
||||||
|
|
||||||
while (usedValues.contains(s2) || s1 + AwgConstant::messageInitiationSize == s2 + AwgConstant::messageResponseSize) {
|
|
||||||
s2 = QRandomGenerator::global()->bounded(15, 150);
|
s2 = QRandomGenerator::global()->bounded(15, 150);
|
||||||
}
|
}
|
||||||
usedValues.insert(s2);
|
|
||||||
|
|
||||||
// while (usedValues.contains(s3)
|
|
||||||
// || s1 + AwgConstant::messageInitiationSize == s3 + AwgConstant::messageCookieReplySize
|
|
||||||
// || s2 + AwgConstant::messageResponseSize == s3 + AwgConstant::messageCookieReplySize) {
|
|
||||||
// s3 = QRandomGenerator::global()->bounded(15, 150);
|
|
||||||
// }
|
|
||||||
// usedValues.insert(s3);
|
|
||||||
|
|
||||||
// while (usedValues.contains(s4)
|
|
||||||
// || s1 + AwgConstant::messageInitiationSize == s4 + AwgConstant::messageTransportSize
|
|
||||||
// || s2 + AwgConstant::messageResponseSize == s4 + AwgConstant::messageTransportSize
|
|
||||||
// || s3 + AwgConstant::messageCookieReplySize == s4 + AwgConstant::messageTransportSize) {
|
|
||||||
// s4 = QRandomGenerator::global()->bounded(15, 150);
|
|
||||||
// }
|
|
||||||
|
|
||||||
QString initPacketJunkSize = QString::number(s1);
|
QString initPacketJunkSize = QString::number(s1);
|
||||||
QString responsePacketJunkSize = QString::number(s2);
|
QString responsePacketJunkSize = QString::number(s2);
|
||||||
// QString cookieReplyPacketJunkSize = QString::number(s3);
|
|
||||||
// QString transportPacketJunkSize = QString::number(s4);
|
|
||||||
|
|
||||||
QSet<QString> headersValue;
|
QSet<QString> headersValue;
|
||||||
while (headersValue.size() != 4) {
|
while (headersValue.size() != 4) {
|
||||||
|
|
@ -132,21 +108,6 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||||
containerConfig[config_key::responsePacketMagicHeader] = responsePacketMagicHeader;
|
containerConfig[config_key::responsePacketMagicHeader] = responsePacketMagicHeader;
|
||||||
containerConfig[config_key::underloadPacketMagicHeader] = underloadPacketMagicHeader;
|
containerConfig[config_key::underloadPacketMagicHeader] = underloadPacketMagicHeader;
|
||||||
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
|
containerConfig[config_key::transportPacketMagicHeader] = transportPacketMagicHeader;
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// containerConfig[config_key::cookieReplyPacketJunkSize] = cookieReplyPacketJunkSize;
|
|
||||||
// containerConfig[config_key::transportPacketJunkSize] = transportPacketJunkSize;
|
|
||||||
|
|
||||||
// containerConfig[config_key::specialJunk1] = specialJunk1;
|
|
||||||
// containerConfig[config_key::specialJunk2] = specialJunk2;
|
|
||||||
// containerConfig[config_key::specialJunk3] = specialJunk3;
|
|
||||||
// containerConfig[config_key::specialJunk4] = specialJunk4;
|
|
||||||
// containerConfig[config_key::specialJunk5] = specialJunk5;
|
|
||||||
// containerConfig[config_key::controlledJunk1] = controlledJunk1;
|
|
||||||
// containerConfig[config_key::controlledJunk2] = controlledJunk2;
|
|
||||||
// containerConfig[config_key::controlledJunk3] = controlledJunk3;
|
|
||||||
// containerConfig[config_key::specialHandshakeTimeout] = specialHandshakeTimeout;
|
|
||||||
|
|
||||||
} else if (container == DockerContainer::Sftp) {
|
} else if (container == DockerContainer::Sftp) {
|
||||||
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
|
containerConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
|
||||||
containerConfig.insert(config_key::password, Utils::getRandomString(16));
|
containerConfig.insert(config_key::password, Utils::getRandomString(16));
|
||||||
|
|
@ -402,8 +363,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
||||||
|
|
||||||
QJsonObject config;
|
QJsonObject config;
|
||||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
const auto &protocols = ContainerProps::protocolsForContainer(container);
|
for (auto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
for (const auto &protocol : protocols) {
|
|
||||||
QJsonObject containerConfig;
|
QJsonObject containerConfig;
|
||||||
if (protocol == mainProto) {
|
if (protocol == mainProto) {
|
||||||
containerConfig.insert(config_key::port, port);
|
containerConfig.insert(config_key::port, port);
|
||||||
|
|
@ -427,7 +387,6 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
containerConfig[config_key::subnet_address] = serverConfigMap.value("Address").remove("/24");
|
|
||||||
containerConfig[config_key::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
|
containerConfig[config_key::junkPacketCount] = serverConfigMap.value(config_key::junkPacketCount);
|
||||||
containerConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
|
containerConfig[config_key::junkPacketMinSize] = serverConfigMap.value(config_key::junkPacketMinSize);
|
||||||
containerConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
|
containerConfig[config_key::junkPacketMaxSize] = serverConfigMap.value(config_key::junkPacketMaxSize);
|
||||||
|
|
@ -439,38 +398,6 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
||||||
serverConfigMap.value(config_key::underloadPacketMagicHeader);
|
serverConfigMap.value(config_key::underloadPacketMagicHeader);
|
||||||
containerConfig[config_key::transportPacketMagicHeader] =
|
containerConfig[config_key::transportPacketMagicHeader] =
|
||||||
serverConfigMap.value(config_key::transportPacketMagicHeader);
|
serverConfigMap.value(config_key::transportPacketMagicHeader);
|
||||||
|
|
||||||
// containerConfig[config_key::cookieReplyPacketJunkSize] = serverConfigMap.value(config_key::cookieReplyPacketJunkSize);
|
|
||||||
// containerConfig[config_key::transportPacketJunkSize] = serverConfigMap.value(config_key::transportPacketJunkSize);
|
|
||||||
|
|
||||||
// containerConfig[config_key::specialJunk1] = serverConfigMap.value(config_key::specialJunk1);
|
|
||||||
// containerConfig[config_key::specialJunk2] = serverConfigMap.value(config_key::specialJunk2);
|
|
||||||
// containerConfig[config_key::specialJunk3] = serverConfigMap.value(config_key::specialJunk3);
|
|
||||||
// containerConfig[config_key::specialJunk4] = serverConfigMap.value(config_key::specialJunk4);
|
|
||||||
// containerConfig[config_key::specialJunk5] = serverConfigMap.value(config_key::specialJunk5);
|
|
||||||
// containerConfig[config_key::controlledJunk1] = serverConfigMap.value(config_key::controlledJunk1);
|
|
||||||
// containerConfig[config_key::controlledJunk2] = serverConfigMap.value(config_key::controlledJunk2);
|
|
||||||
// containerConfig[config_key::controlledJunk3] = serverConfigMap.value(config_key::controlledJunk3);
|
|
||||||
// containerConfig[config_key::specialHandshakeTimeout] = serverConfigMap.value(config_key::specialHandshakeTimeout);
|
|
||||||
|
|
||||||
} else if (protocol == Proto::WireGuard) {
|
|
||||||
QString serverConfig = serverController->getTextFileFromContainer(container, credentials,
|
|
||||||
protocols::wireguard::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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
containerConfig[config_key::subnet_address] = serverConfigMap.value("Address").remove("/24");
|
|
||||||
} else if (protocol == Proto::Sftp) {
|
} else if (protocol == Proto::Sftp) {
|
||||||
stdOut.clear();
|
stdOut.clear();
|
||||||
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
script = QString("sudo docker inspect --format '{{.Config.Cmd}}' %1").arg(name);
|
||||||
|
|
@ -505,51 +432,6 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
|
||||||
containerConfig.insert(config_key::userName, userName);
|
containerConfig.insert(config_key::userName, userName);
|
||||||
containerConfig.insert(config_key::password, password);
|
containerConfig.insert(config_key::password, password);
|
||||||
}
|
}
|
||||||
} else if (protocol == Proto::Xray) {
|
|
||||||
QString currentConfig = serverController->getTextFileFromContainer(
|
|
||||||
container, credentials, amnezia::protocols::xray::serverConfigPath, errorCode);
|
|
||||||
|
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(currentConfig.toUtf8());
|
|
||||||
qDebug() << doc;
|
|
||||||
if (doc.isNull() || !doc.isObject()) {
|
|
||||||
logger.error() << "Failed to parse server config JSON";
|
|
||||||
errorCode = ErrorCode::InternalError;
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
QJsonObject serverConfig = doc.object();
|
|
||||||
|
|
||||||
if (!serverConfig.contains("inbounds")) {
|
|
||||||
logger.error() << "Server config missing 'inbounds' field";
|
|
||||||
errorCode = ErrorCode::InternalError;
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonArray inbounds = serverConfig["inbounds"].toArray();
|
|
||||||
if (inbounds.isEmpty()) {
|
|
||||||
logger.error() << "Server config has empty 'inbounds' array";
|
|
||||||
errorCode = ErrorCode::InternalError;
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject inbound = inbounds[0].toObject();
|
|
||||||
if (!inbound.contains("streamSettings")) {
|
|
||||||
logger.error() << "Inbound missing 'streamSettings' field";
|
|
||||||
errorCode = ErrorCode::InternalError;
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonObject streamSettings = inbound["streamSettings"].toObject();
|
|
||||||
QJsonObject realitySettings = streamSettings["realitySettings"].toObject();
|
|
||||||
if (!realitySettings.contains("serverNames")) {
|
|
||||||
logger.error() << "Settings missing 'clients' field";
|
|
||||||
errorCode = ErrorCode::InternalError;
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString siteName = realitySettings["serverNames"][0].toString();
|
|
||||||
qDebug() << siteName;
|
|
||||||
|
|
||||||
containerConfig.insert(config_key::site, siteName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config.insert(config_key::container, ContainerProps::containerToString(container));
|
config.insert(config_key::container, ContainerProps::containerToString(container));
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,13 @@ namespace PageLoader
|
||||||
PageSettingsLogging,
|
PageSettingsLogging,
|
||||||
PageSettingsSplitTunneling,
|
PageSettingsSplitTunneling,
|
||||||
PageSettingsAppSplitTunneling,
|
PageSettingsAppSplitTunneling,
|
||||||
PageSettingsKillSwitch,
|
|
||||||
PageSettingsApiServerInfo,
|
PageSettingsApiServerInfo,
|
||||||
PageSettingsApiAvailableCountries,
|
PageSettingsApiAvailableCountries,
|
||||||
PageSettingsApiSupport,
|
PageSettingsApiSupport,
|
||||||
PageSettingsApiInstructions,
|
PageSettingsApiInstructions,
|
||||||
PageSettingsApiNativeConfigs,
|
PageSettingsApiNativeConfigs,
|
||||||
PageSettingsApiDevices,
|
PageSettingsApiDevices,
|
||||||
PageSettingsKillSwitchExceptions,
|
|
||||||
|
|
||||||
PageServiceSftpSettings,
|
PageServiceSftpSettings,
|
||||||
PageServiceTorWebsiteSettings,
|
PageServiceTorWebsiteSettings,
|
||||||
PageServiceDnsSettings,
|
PageServiceDnsSettings,
|
||||||
|
|
|
||||||
|
|
@ -126,13 +126,7 @@ void SettingsController::clearLogs()
|
||||||
|
|
||||||
void SettingsController::backupAppConfig(const QString &fileName)
|
void SettingsController::backupAppConfig(const QString &fileName)
|
||||||
{
|
{
|
||||||
QByteArray data = m_settings->backupAppConfig();
|
SystemController::saveFile(fileName, m_settings->backupAppConfig());
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
|
||||||
QJsonObject config = doc.object();
|
|
||||||
|
|
||||||
config["Conf/autoStart"] = Autostart::isAutostart();
|
|
||||||
|
|
||||||
SystemController::saveFile(fileName, QJsonDocument(config).toJson());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsController::restoreAppConfig(const QString &fileName)
|
void SettingsController::restoreAppConfig(const QString &fileName)
|
||||||
|
|
@ -146,30 +140,9 @@ void SettingsController::restoreAppConfigFromData(const QByteArray &data)
|
||||||
{
|
{
|
||||||
bool ok = m_settings->restoreAppConfig(data);
|
bool ok = m_settings->restoreAppConfig(data);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
QJsonObject newConfigData = QJsonDocument::fromJson(data).object();
|
|
||||||
|
|
||||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_LINUX) || defined(Q_OS_MACX)
|
|
||||||
bool autoStart = false;
|
|
||||||
if (newConfigData.contains("Conf/autoStart")) {
|
|
||||||
autoStart = newConfigData["Conf/autoStart"].toBool();
|
|
||||||
}
|
|
||||||
toggleAutoStart(autoStart);
|
|
||||||
#endif
|
|
||||||
m_serversModel->resetModel();
|
m_serversModel->resetModel();
|
||||||
m_languageModel->changeLanguage(
|
m_languageModel->changeLanguage(
|
||||||
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||||
|
|
||||||
#if defined(Q_OS_WINDOWS) || defined(Q_OS_ANDROID)
|
|
||||||
int appSplitTunnelingRouteMode = newConfigData.value("Conf/appsRouteMode").toInt();
|
|
||||||
bool appSplittunnelingEnabled = newConfigData.value("Conf/appsSplitTunnelingEnabled").toBool();
|
|
||||||
m_appSplitTunnelingModel->setRouteMode(appSplitTunnelingRouteMode);
|
|
||||||
m_appSplitTunnelingModel->toggleSplitTunneling(appSplittunnelingEnabled);
|
|
||||||
#endif
|
|
||||||
int siteSplitTunnelingRouteMode = newConfigData.value("Conf/routeMode").toInt();
|
|
||||||
bool siteSplittunnelingEnabled = newConfigData.value("Conf/sitesSplitTunnelingEnabled").toBool();
|
|
||||||
m_sitesModel->setRouteMode(siteSplitTunnelingRouteMode);
|
|
||||||
m_sitesModel->toggleSplitTunneling(siteSplittunnelingEnabled);
|
|
||||||
|
|
||||||
emit restoreBackupFinished();
|
emit restoreBackupFinished();
|
||||||
} else {
|
} else {
|
||||||
emit changeSettingsErrorOccurred(tr("Backup file is corrupted"));
|
emit changeSettingsErrorOccurred(tr("Backup file is corrupted"));
|
||||||
|
|
@ -194,8 +167,6 @@ void SettingsController::clearSettings()
|
||||||
m_appSplitTunnelingModel->setRouteMode(Settings::AppsRouteMode::VpnAllExceptApps);
|
m_appSplitTunnelingModel->setRouteMode(Settings::AppsRouteMode::VpnAllExceptApps);
|
||||||
m_appSplitTunnelingModel->toggleSplitTunneling(false);
|
m_appSplitTunnelingModel->toggleSplitTunneling(false);
|
||||||
|
|
||||||
toggleAutoStart(false);
|
|
||||||
|
|
||||||
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
||||||
|
|
||||||
#ifdef Q_OS_IOS
|
#ifdef Q_OS_IOS
|
||||||
|
|
@ -274,23 +245,6 @@ bool SettingsController::isKillSwitchEnabled()
|
||||||
void SettingsController::toggleKillSwitch(bool enable)
|
void SettingsController::toggleKillSwitch(bool enable)
|
||||||
{
|
{
|
||||||
m_settings->setKillSwitchEnabled(enable);
|
m_settings->setKillSwitchEnabled(enable);
|
||||||
emit killSwitchEnabledChanged();
|
|
||||||
if (enable == false) {
|
|
||||||
emit strictKillSwitchEnabledChanged(false);
|
|
||||||
} else {
|
|
||||||
emit strictKillSwitchEnabledChanged(isStrictKillSwitchEnabled());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SettingsController::isStrictKillSwitchEnabled()
|
|
||||||
{
|
|
||||||
return m_settings->isStrictKillSwitchEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SettingsController::toggleStrictKillSwitch(bool enable)
|
|
||||||
{
|
|
||||||
m_settings->setStrictKillSwitchEnabled(enable);
|
|
||||||
emit strictKillSwitchEnabledChanged(enable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsController::isNotificationPermissionGranted()
|
bool SettingsController::isNotificationPermissionGranted()
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ public:
|
||||||
Q_PROPERTY(QString secondaryDns READ getSecondaryDns WRITE setSecondaryDns NOTIFY secondaryDnsChanged)
|
Q_PROPERTY(QString secondaryDns READ getSecondaryDns WRITE setSecondaryDns NOTIFY secondaryDnsChanged)
|
||||||
Q_PROPERTY(bool isLoggingEnabled READ isLoggingEnabled WRITE toggleLogging NOTIFY loggingStateChanged)
|
Q_PROPERTY(bool isLoggingEnabled READ isLoggingEnabled WRITE toggleLogging NOTIFY loggingStateChanged)
|
||||||
Q_PROPERTY(bool isNotificationPermissionGranted READ isNotificationPermissionGranted NOTIFY onNotificationStateChanged)
|
Q_PROPERTY(bool isNotificationPermissionGranted READ isNotificationPermissionGranted NOTIFY onNotificationStateChanged)
|
||||||
Q_PROPERTY(bool isKillSwitchEnabled READ isKillSwitchEnabled WRITE toggleKillSwitch NOTIFY killSwitchEnabledChanged)
|
|
||||||
Q_PROPERTY(bool strictKillSwitchEnabled READ isStrictKillSwitchEnabled WRITE toggleStrictKillSwitch NOTIFY strictKillSwitchEnabledChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(bool isDevModeEnabled READ isDevModeEnabled NOTIFY devModeEnabled)
|
Q_PROPERTY(bool isDevModeEnabled READ isDevModeEnabled NOTIFY devModeEnabled)
|
||||||
Q_PROPERTY(QString gatewayEndpoint READ getGatewayEndpoint WRITE setGatewayEndpoint NOTIFY gatewayEndpointChanged)
|
Q_PROPERTY(QString gatewayEndpoint READ getGatewayEndpoint WRITE setGatewayEndpoint NOTIFY gatewayEndpointChanged)
|
||||||
|
|
@ -77,9 +75,6 @@ public slots:
|
||||||
bool isKillSwitchEnabled();
|
bool isKillSwitchEnabled();
|
||||||
void toggleKillSwitch(bool enable);
|
void toggleKillSwitch(bool enable);
|
||||||
|
|
||||||
bool isStrictKillSwitchEnabled();
|
|
||||||
void toggleStrictKillSwitch(bool enable);
|
|
||||||
|
|
||||||
bool isNotificationPermissionGranted();
|
bool isNotificationPermissionGranted();
|
||||||
void requestNotificationPermission();
|
void requestNotificationPermission();
|
||||||
|
|
||||||
|
|
@ -103,8 +98,6 @@ signals:
|
||||||
void primaryDnsChanged();
|
void primaryDnsChanged();
|
||||||
void secondaryDnsChanged();
|
void secondaryDnsChanged();
|
||||||
void loggingStateChanged();
|
void loggingStateChanged();
|
||||||
void killSwitchEnabledChanged();
|
|
||||||
void strictKillSwitchEnabledChanged(bool enabled);
|
|
||||||
|
|
||||||
void restoreBackupFinished();
|
void restoreBackupFinished();
|
||||||
void changeSettingsFinished(const QString &finishedMessage);
|
void changeSettingsFinished(const QString &finishedMessage);
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
#include "allowed_dns_model.h"
|
|
||||||
|
|
||||||
AllowedDnsModel::AllowedDnsModel(std::shared_ptr<Settings> settings, QObject *parent)
|
|
||||||
: QAbstractListModel(parent), m_settings(settings)
|
|
||||||
{
|
|
||||||
fillDnsServers();
|
|
||||||
}
|
|
||||||
|
|
||||||
int AllowedDnsModel::rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(parent)
|
|
||||||
return m_dnsServers.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant AllowedDnsModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(rowCount()))
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case IpRole:
|
|
||||||
return m_dnsServers.at(index.row());
|
|
||||||
default:
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AllowedDnsModel::addDns(const QString &ip)
|
|
||||||
{
|
|
||||||
if (m_dnsServers.contains(ip)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
|
||||||
m_dnsServers.append(ip);
|
|
||||||
m_settings->setAllowedDnsServers(m_dnsServers);
|
|
||||||
endInsertRows();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllowedDnsModel::addDnsList(const QStringList &dnsServers, bool replaceExisting)
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
|
|
||||||
if (replaceExisting) {
|
|
||||||
m_dnsServers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const QString &ip : dnsServers) {
|
|
||||||
if (!m_dnsServers.contains(ip)) {
|
|
||||||
m_dnsServers.append(ip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_settings->setAllowedDnsServers(m_dnsServers);
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllowedDnsModel::removeDns(QModelIndex index)
|
|
||||||
{
|
|
||||||
if (!index.isValid() || index.row() >= m_dnsServers.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
beginRemoveRows(QModelIndex(), index.row(), index.row());
|
|
||||||
m_dnsServers.removeAt(index.row());
|
|
||||||
m_settings->setAllowedDnsServers(m_dnsServers);
|
|
||||||
endRemoveRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList AllowedDnsModel::getCurrentDnsServers()
|
|
||||||
{
|
|
||||||
return m_dnsServers;
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<int, QByteArray> AllowedDnsModel::roleNames() const
|
|
||||||
{
|
|
||||||
QHash<int, QByteArray> roles;
|
|
||||||
roles[IpRole] = "ip";
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AllowedDnsModel::fillDnsServers()
|
|
||||||
{
|
|
||||||
m_dnsServers = m_settings->allowedDnsServers();
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
#ifndef ALLOWEDDNSMODEL_H
|
|
||||||
#define ALLOWEDDNSMODEL_H
|
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
#include "settings.h"
|
|
||||||
|
|
||||||
class AllowedDnsModel : public QAbstractListModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum Roles {
|
|
||||||
IpRole = Qt::UserRole + 1
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit AllowedDnsModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
bool addDns(const QString &ip);
|
|
||||||
void addDnsList(const QStringList &dnsServers, bool replaceExisting);
|
|
||||||
void removeDns(QModelIndex index);
|
|
||||||
QStringList getCurrentDnsServers();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void fillDnsServers();
|
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
|
||||||
QStringList m_dnsServers;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ALLOWEDDNSMODEL_H
|
|
||||||
|
|
@ -75,12 +75,6 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case IsProtocolSelectionSupportedRole: {
|
|
||||||
if (m_accountInfoData.supportedProtocols.size() > 1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
@ -101,10 +95,6 @@ void ApiAccountInfoModel::updateModel(const QJsonObject &accountInfoObject, cons
|
||||||
|
|
||||||
accountInfoData.configType = apiUtils::getConfigType(serverConfig);
|
accountInfoData.configType = apiUtils::getConfigType(serverConfig);
|
||||||
|
|
||||||
for (const auto &protocol : accountInfoObject.value(apiDefs::key::supportedProtocols).toArray()) {
|
|
||||||
accountInfoData.supportedProtocols.push_back(protocol.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_accountInfoData = accountInfoData;
|
m_accountInfoData = accountInfoData;
|
||||||
|
|
||||||
m_supportInfo = accountInfoObject.value(apiDefs::key::supportInfo).toObject();
|
m_supportInfo = accountInfoObject.value(apiDefs::key::supportInfo).toObject();
|
||||||
|
|
@ -169,7 +159,6 @@ QHash<int, QByteArray> ApiAccountInfoModel::roleNames() const
|
||||||
roles[ServiceDescriptionRole] = "serviceDescription";
|
roles[ServiceDescriptionRole] = "serviceDescription";
|
||||||
roles[IsComponentVisibleRole] = "isComponentVisible";
|
roles[IsComponentVisibleRole] = "isComponentVisible";
|
||||||
roles[HasExpiredWorkerRole] = "hasExpiredWorker";
|
roles[HasExpiredWorkerRole] = "hasExpiredWorker";
|
||||||
roles[IsProtocolSelectionSupportedRole] = "isProtocolSelectionSupported";
|
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,7 @@ public:
|
||||||
ServiceDescriptionRole,
|
ServiceDescriptionRole,
|
||||||
EndDateRole,
|
EndDateRole,
|
||||||
IsComponentVisibleRole,
|
IsComponentVisibleRole,
|
||||||
HasExpiredWorkerRole,
|
HasExpiredWorkerRole
|
||||||
IsProtocolSelectionSupportedRole
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ApiAccountInfoModel(QObject *parent = nullptr);
|
explicit ApiAccountInfoModel(QObject *parent = nullptr);
|
||||||
|
|
@ -52,8 +51,6 @@ private:
|
||||||
int maxDeviceCount;
|
int maxDeviceCount;
|
||||||
|
|
||||||
apiDefs::ConfigType configType;
|
apiDefs::ConfigType configType;
|
||||||
|
|
||||||
QStringList supportedProtocols;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AccountInfoData m_accountInfoData;
|
AccountInfoData m_accountInfoData;
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||||
"Access all websites and online resources. Speeds up to %1 Mbps.")
|
"Access all websites and online resources. Speeds up to %1 Mbps.")
|
||||||
.arg(speed);
|
.arg(speed);
|
||||||
} else if (serviceType == serviceType::amneziaFree) {
|
} else if (serviceType == serviceType::amneziaFree) {
|
||||||
QString description = tr("Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan.");
|
QString description = tr("AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan.");
|
||||||
if (!isServiceAvailable) {
|
if (!isServiceAvailable) {
|
||||||
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, "
|
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, "
|
||||||
"return to the previous screen, and try again.</a>");
|
"return to the previous screen, and try again.</a>");
|
||||||
|
|
@ -82,7 +82,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
|
||||||
return tr("Amnezia Premium is classic VPN for for seamless work, downloading large files, and watching videos. "
|
return tr("Amnezia Premium is classic VPN for for seamless work, downloading large files, and watching videos. "
|
||||||
"Access all websites and online resources.");
|
"Access all websites and online resources.");
|
||||||
} else {
|
} else {
|
||||||
return tr("Amnezia Free provides unlimited, free access to a basic set of websites and apps, including Facebook, Instagram, Twitter (X), Discord, Telegram, and more. YouTube is not included in the free plan.");
|
return tr("AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case IsServiceAvailableRole: {
|
case IsServiceAvailableRole: {
|
||||||
|
|
|
||||||
|
|
@ -28,17 +28,7 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||||
case Roles::ClientJunkPacketCountRole: m_clientProtocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
|
case Roles::ClientJunkPacketCountRole: m_clientProtocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
|
||||||
case Roles::ClientJunkPacketMinSizeRole: m_clientProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
|
case Roles::ClientJunkPacketMinSizeRole: m_clientProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
|
||||||
case Roles::ClientJunkPacketMaxSizeRole: m_clientProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
|
case Roles::ClientJunkPacketMaxSizeRole: m_clientProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
|
||||||
case Roles::ClientSpecialJunk1Role: m_clientProtocolConfig.insert(config_key::specialJunk1, value.toString()); break;
|
|
||||||
case Roles::ClientSpecialJunk2Role: m_clientProtocolConfig.insert(config_key::specialJunk2, value.toString()); break;
|
|
||||||
case Roles::ClientSpecialJunk3Role: m_clientProtocolConfig.insert(config_key::specialJunk3, value.toString()); break;
|
|
||||||
case Roles::ClientSpecialJunk4Role: m_clientProtocolConfig.insert(config_key::specialJunk4, value.toString()); break;
|
|
||||||
case Roles::ClientSpecialJunk5Role: m_clientProtocolConfig.insert(config_key::specialJunk5, value.toString()); break;
|
|
||||||
case Roles::ClientControlledJunk1Role: m_clientProtocolConfig.insert(config_key::controlledJunk1, value.toString()); break;
|
|
||||||
case Roles::ClientControlledJunk2Role: m_clientProtocolConfig.insert(config_key::controlledJunk2, value.toString()); break;
|
|
||||||
case Roles::ClientControlledJunk3Role: m_clientProtocolConfig.insert(config_key::controlledJunk3, value.toString()); break;
|
|
||||||
case Roles::ClientSpecialHandshakeTimeoutRole:
|
|
||||||
m_clientProtocolConfig.insert(config_key::specialHandshakeTimeout, value.toString());
|
|
||||||
break;
|
|
||||||
case Roles::ServerJunkPacketCountRole: m_serverProtocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
|
case Roles::ServerJunkPacketCountRole: m_serverProtocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
|
||||||
case Roles::ServerJunkPacketMinSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
|
case Roles::ServerJunkPacketMinSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
|
||||||
case Roles::ServerJunkPacketMaxSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
|
case Roles::ServerJunkPacketMaxSizeRole: m_serverProtocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
|
||||||
|
|
@ -46,12 +36,6 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||||
case Roles::ServerResponsePacketJunkSizeRole:
|
case Roles::ServerResponsePacketJunkSizeRole:
|
||||||
m_serverProtocolConfig.insert(config_key::responsePacketJunkSize, value.toString());
|
m_serverProtocolConfig.insert(config_key::responsePacketJunkSize, value.toString());
|
||||||
break;
|
break;
|
||||||
// case Roles::ServerCookieReplyPacketJunkSizeRole:
|
|
||||||
// m_serverProtocolConfig.insert(config_key::cookieReplyPacketJunkSize, value.toString());
|
|
||||||
// break;
|
|
||||||
// case Roles::ServerTransportPacketJunkSizeRole:
|
|
||||||
// m_serverProtocolConfig.insert(config_key::transportPacketJunkSize, value.toString());
|
|
||||||
// break;
|
|
||||||
case Roles::ServerInitPacketMagicHeaderRole: m_serverProtocolConfig.insert(config_key::initPacketMagicHeader, value.toString()); break;
|
case Roles::ServerInitPacketMagicHeaderRole: m_serverProtocolConfig.insert(config_key::initPacketMagicHeader, value.toString()); break;
|
||||||
case Roles::ServerResponsePacketMagicHeaderRole:
|
case Roles::ServerResponsePacketMagicHeaderRole:
|
||||||
m_serverProtocolConfig.insert(config_key::responsePacketMagicHeader, value.toString());
|
m_serverProtocolConfig.insert(config_key::responsePacketMagicHeader, value.toString());
|
||||||
|
|
@ -82,23 +66,12 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
|
||||||
case Roles::ClientJunkPacketCountRole: return m_clientProtocolConfig.value(config_key::junkPacketCount);
|
case Roles::ClientJunkPacketCountRole: return m_clientProtocolConfig.value(config_key::junkPacketCount);
|
||||||
case Roles::ClientJunkPacketMinSizeRole: return m_clientProtocolConfig.value(config_key::junkPacketMinSize);
|
case Roles::ClientJunkPacketMinSizeRole: return m_clientProtocolConfig.value(config_key::junkPacketMinSize);
|
||||||
case Roles::ClientJunkPacketMaxSizeRole: return m_clientProtocolConfig.value(config_key::junkPacketMaxSize);
|
case Roles::ClientJunkPacketMaxSizeRole: return m_clientProtocolConfig.value(config_key::junkPacketMaxSize);
|
||||||
case Roles::ClientSpecialJunk1Role: return m_clientProtocolConfig.value(config_key::specialJunk1);
|
|
||||||
case Roles::ClientSpecialJunk2Role: return m_clientProtocolConfig.value(config_key::specialJunk2);
|
|
||||||
case Roles::ClientSpecialJunk3Role: return m_clientProtocolConfig.value(config_key::specialJunk3);
|
|
||||||
case Roles::ClientSpecialJunk4Role: return m_clientProtocolConfig.value(config_key::specialJunk4);
|
|
||||||
case Roles::ClientSpecialJunk5Role: return m_clientProtocolConfig.value(config_key::specialJunk5);
|
|
||||||
case Roles::ClientControlledJunk1Role: return m_clientProtocolConfig.value(config_key::controlledJunk1);
|
|
||||||
case Roles::ClientControlledJunk2Role: return m_clientProtocolConfig.value(config_key::controlledJunk2);
|
|
||||||
case Roles::ClientControlledJunk3Role: return m_clientProtocolConfig.value(config_key::controlledJunk3);
|
|
||||||
case Roles::ClientSpecialHandshakeTimeoutRole: return m_clientProtocolConfig.value(config_key::specialHandshakeTimeout);
|
|
||||||
|
|
||||||
case Roles::ServerJunkPacketCountRole: return m_serverProtocolConfig.value(config_key::junkPacketCount);
|
case Roles::ServerJunkPacketCountRole: return m_serverProtocolConfig.value(config_key::junkPacketCount);
|
||||||
case Roles::ServerJunkPacketMinSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMinSize);
|
case Roles::ServerJunkPacketMinSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMinSize);
|
||||||
case Roles::ServerJunkPacketMaxSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMaxSize);
|
case Roles::ServerJunkPacketMaxSizeRole: return m_serverProtocolConfig.value(config_key::junkPacketMaxSize);
|
||||||
case Roles::ServerInitPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::initPacketJunkSize);
|
case Roles::ServerInitPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::initPacketJunkSize);
|
||||||
case Roles::ServerResponsePacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::responsePacketJunkSize);
|
case Roles::ServerResponsePacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::responsePacketJunkSize);
|
||||||
// case Roles::ServerCookieReplyPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize);
|
|
||||||
// case Roles::ServerTransportPacketJunkSizeRole: return m_serverProtocolConfig.value(config_key::transportPacketJunkSize);
|
|
||||||
case Roles::ServerInitPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::initPacketMagicHeader);
|
case Roles::ServerInitPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::initPacketMagicHeader);
|
||||||
case Roles::ServerResponsePacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::responsePacketMagicHeader);
|
case Roles::ServerResponsePacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::responsePacketMagicHeader);
|
||||||
case Roles::ServerUnderloadPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::underloadPacketMagicHeader);
|
case Roles::ServerUnderloadPacketMagicHeaderRole: return m_serverProtocolConfig.value(config_key::underloadPacketMagicHeader);
|
||||||
|
|
@ -121,8 +94,7 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
|
||||||
m_serverProtocolConfig.insert(config_key::transport_proto,
|
m_serverProtocolConfig.insert(config_key::transport_proto,
|
||||||
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
|
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
|
||||||
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
|
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
|
||||||
m_serverProtocolConfig[config_key::subnet_address] =
|
m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||||
serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
|
||||||
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
||||||
m_serverProtocolConfig[config_key::junkPacketCount] =
|
m_serverProtocolConfig[config_key::junkPacketCount] =
|
||||||
serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
||||||
|
|
@ -134,10 +106,6 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
|
||||||
serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
|
serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
|
||||||
m_serverProtocolConfig[config_key::responsePacketJunkSize] =
|
m_serverProtocolConfig[config_key::responsePacketJunkSize] =
|
||||||
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
|
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
|
||||||
// m_serverProtocolConfig[config_key::cookieReplyPacketJunkSize] =
|
|
||||||
// serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
|
|
||||||
// m_serverProtocolConfig[config_key::transportPacketJunkSize] =
|
|
||||||
// serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
|
|
||||||
m_serverProtocolConfig[config_key::initPacketMagicHeader] =
|
m_serverProtocolConfig[config_key::initPacketMagicHeader] =
|
||||||
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
|
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
|
||||||
m_serverProtocolConfig[config_key::responsePacketMagicHeader] =
|
m_serverProtocolConfig[config_key::responsePacketMagicHeader] =
|
||||||
|
|
@ -156,24 +124,6 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
|
||||||
clientProtocolConfig.value(config_key::junkPacketMinSize).toString(m_serverProtocolConfig[config_key::junkPacketMinSize].toString());
|
clientProtocolConfig.value(config_key::junkPacketMinSize).toString(m_serverProtocolConfig[config_key::junkPacketMinSize].toString());
|
||||||
m_clientProtocolConfig[config_key::junkPacketMaxSize] =
|
m_clientProtocolConfig[config_key::junkPacketMaxSize] =
|
||||||
clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(m_serverProtocolConfig[config_key::junkPacketMaxSize].toString());
|
clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(m_serverProtocolConfig[config_key::junkPacketMaxSize].toString());
|
||||||
m_clientProtocolConfig[config_key::specialJunk1] =
|
|
||||||
clientProtocolConfig.value(config_key::specialJunk1).toString(protocols::awg::defaultSpecialJunk1);
|
|
||||||
m_clientProtocolConfig[config_key::specialJunk2] =
|
|
||||||
clientProtocolConfig.value(config_key::specialJunk2).toString(protocols::awg::defaultSpecialJunk2);
|
|
||||||
m_clientProtocolConfig[config_key::specialJunk3] =
|
|
||||||
clientProtocolConfig.value(config_key::specialJunk3).toString(protocols::awg::defaultSpecialJunk3);
|
|
||||||
m_clientProtocolConfig[config_key::specialJunk4] =
|
|
||||||
clientProtocolConfig.value(config_key::specialJunk4).toString(protocols::awg::defaultSpecialJunk4);
|
|
||||||
m_clientProtocolConfig[config_key::specialJunk5] =
|
|
||||||
clientProtocolConfig.value(config_key::specialJunk5).toString(protocols::awg::defaultSpecialJunk5);
|
|
||||||
m_clientProtocolConfig[config_key::controlledJunk1] =
|
|
||||||
clientProtocolConfig.value(config_key::controlledJunk1).toString(protocols::awg::defaultControlledJunk1);
|
|
||||||
m_clientProtocolConfig[config_key::controlledJunk2] =
|
|
||||||
clientProtocolConfig.value(config_key::controlledJunk2).toString(protocols::awg::defaultControlledJunk2);
|
|
||||||
m_clientProtocolConfig[config_key::controlledJunk3] =
|
|
||||||
clientProtocolConfig.value(config_key::controlledJunk3).toString(protocols::awg::defaultControlledJunk3);
|
|
||||||
m_clientProtocolConfig[config_key::specialHandshakeTimeout] =
|
|
||||||
clientProtocolConfig.value(config_key::specialHandshakeTimeout).toString(protocols::awg::defaultSpecialHandshakeTimeout);
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,15 +141,6 @@ QJsonObject AwgConfigModel::getConfig()
|
||||||
jsonConfig[config_key::junkPacketCount] = m_clientProtocolConfig[config_key::junkPacketCount];
|
jsonConfig[config_key::junkPacketCount] = m_clientProtocolConfig[config_key::junkPacketCount];
|
||||||
jsonConfig[config_key::junkPacketMinSize] = m_clientProtocolConfig[config_key::junkPacketMinSize];
|
jsonConfig[config_key::junkPacketMinSize] = m_clientProtocolConfig[config_key::junkPacketMinSize];
|
||||||
jsonConfig[config_key::junkPacketMaxSize] = m_clientProtocolConfig[config_key::junkPacketMaxSize];
|
jsonConfig[config_key::junkPacketMaxSize] = m_clientProtocolConfig[config_key::junkPacketMaxSize];
|
||||||
jsonConfig[config_key::specialJunk1] = m_clientProtocolConfig[config_key::specialJunk1];
|
|
||||||
jsonConfig[config_key::specialJunk2] = m_clientProtocolConfig[config_key::specialJunk2];
|
|
||||||
jsonConfig[config_key::specialJunk3] = m_clientProtocolConfig[config_key::specialJunk3];
|
|
||||||
jsonConfig[config_key::specialJunk4] = m_clientProtocolConfig[config_key::specialJunk4];
|
|
||||||
jsonConfig[config_key::specialJunk5] = m_clientProtocolConfig[config_key::specialJunk5];
|
|
||||||
jsonConfig[config_key::controlledJunk1] = m_clientProtocolConfig[config_key::controlledJunk1];
|
|
||||||
jsonConfig[config_key::controlledJunk2] = m_clientProtocolConfig[config_key::controlledJunk2];
|
|
||||||
jsonConfig[config_key::controlledJunk3] = m_clientProtocolConfig[config_key::controlledJunk3];
|
|
||||||
jsonConfig[config_key::specialHandshakeTimeout] = m_clientProtocolConfig[config_key::specialHandshakeTimeout];
|
|
||||||
|
|
||||||
m_serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
|
m_serverProtocolConfig[config_key::last_config] = QString(QJsonDocument(jsonConfig).toJson());
|
||||||
}
|
}
|
||||||
|
|
@ -218,17 +159,6 @@ bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2)
|
||||||
return (AwgConstant::messageInitiationSize + s1 == AwgConstant::messageResponseSize + s2);
|
return (AwgConstant::messageInitiationSize + s1 == AwgConstant::messageResponseSize + s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool AwgConfigModel::isPacketSizeEqual(const int s1, const int s2, const int s3, const int s4)
|
|
||||||
// {
|
|
||||||
// int initSize = AwgConstant::messageInitiationSize + s1;
|
|
||||||
// int responseSize = AwgConstant::messageResponseSize + s2;
|
|
||||||
// int cookieSize = AwgConstant::messageCookieReplySize + s3;
|
|
||||||
// int transportSize = AwgConstant::messageTransportSize + s4;
|
|
||||||
|
|
||||||
// return (initSize == responseSize || initSize == cookieSize || initSize == transportSize || responseSize == cookieSize
|
|
||||||
// || responseSize == transportSize || cookieSize == transportSize);
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool AwgConfigModel::isServerSettingsEqual()
|
bool AwgConfigModel::isServerSettingsEqual()
|
||||||
{
|
{
|
||||||
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
|
const AwgConfig oldConfig(m_fullConfig.value(config_key::awg).toObject());
|
||||||
|
|
@ -248,24 +178,12 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
|
||||||
roles[ClientJunkPacketCountRole] = "clientJunkPacketCount";
|
roles[ClientJunkPacketCountRole] = "clientJunkPacketCount";
|
||||||
roles[ClientJunkPacketMinSizeRole] = "clientJunkPacketMinSize";
|
roles[ClientJunkPacketMinSizeRole] = "clientJunkPacketMinSize";
|
||||||
roles[ClientJunkPacketMaxSizeRole] = "clientJunkPacketMaxSize";
|
roles[ClientJunkPacketMaxSizeRole] = "clientJunkPacketMaxSize";
|
||||||
roles[ClientSpecialJunk1Role] = "clientSpecialJunk1";
|
|
||||||
roles[ClientSpecialJunk2Role] = "clientSpecialJunk2";
|
|
||||||
roles[ClientSpecialJunk3Role] = "clientSpecialJunk3";
|
|
||||||
roles[ClientSpecialJunk4Role] = "clientSpecialJunk4";
|
|
||||||
roles[ClientSpecialJunk5Role] = "clientSpecialJunk5";
|
|
||||||
roles[ClientControlledJunk1Role] = "clientControlledJunk1";
|
|
||||||
roles[ClientControlledJunk2Role] = "clientControlledJunk2";
|
|
||||||
roles[ClientControlledJunk3Role] = "clientControlledJunk3";
|
|
||||||
roles[ClientSpecialHandshakeTimeoutRole] = "clientSpecialHandshakeTimeout";
|
|
||||||
|
|
||||||
roles[ServerJunkPacketCountRole] = "serverJunkPacketCount";
|
roles[ServerJunkPacketCountRole] = "serverJunkPacketCount";
|
||||||
roles[ServerJunkPacketMinSizeRole] = "serverJunkPacketMinSize";
|
roles[ServerJunkPacketMinSizeRole] = "serverJunkPacketMinSize";
|
||||||
roles[ServerJunkPacketMaxSizeRole] = "serverJunkPacketMaxSize";
|
roles[ServerJunkPacketMaxSizeRole] = "serverJunkPacketMaxSize";
|
||||||
roles[ServerInitPacketJunkSizeRole] = "serverInitPacketJunkSize";
|
roles[ServerInitPacketJunkSizeRole] = "serverInitPacketJunkSize";
|
||||||
roles[ServerResponsePacketJunkSizeRole] = "serverResponsePacketJunkSize";
|
roles[ServerResponsePacketJunkSizeRole] = "serverResponsePacketJunkSize";
|
||||||
roles[ServerCookieReplyPacketJunkSizeRole] = "serverCookieReplyPacketJunkSize";
|
|
||||||
roles[ServerTransportPacketJunkSizeRole] = "serverTransportPacketJunkSize";
|
|
||||||
|
|
||||||
roles[ServerInitPacketMagicHeaderRole] = "serverInitPacketMagicHeader";
|
roles[ServerInitPacketMagicHeaderRole] = "serverInitPacketMagicHeader";
|
||||||
roles[ServerResponsePacketMagicHeaderRole] = "serverResponsePacketMagicHeader";
|
roles[ServerResponsePacketMagicHeaderRole] = "serverResponsePacketMagicHeader";
|
||||||
roles[ServerUnderloadPacketMagicHeaderRole] = "serverUnderloadPacketMagicHeader";
|
roles[ServerUnderloadPacketMagicHeaderRole] = "serverUnderloadPacketMagicHeader";
|
||||||
|
|
@ -282,16 +200,6 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
|
||||||
clientJunkPacketCount = clientProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
clientJunkPacketCount = clientProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
|
||||||
clientJunkPacketMinSize = clientProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
|
clientJunkPacketMinSize = clientProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
|
||||||
clientJunkPacketMaxSize = clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
|
clientJunkPacketMaxSize = clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
|
||||||
clientSpecialJunk1 = clientProtocolConfig.value(config_key::specialJunk1).toString(protocols::awg::defaultSpecialJunk1);
|
|
||||||
clientSpecialJunk2 = clientProtocolConfig.value(config_key::specialJunk2).toString(protocols::awg::defaultSpecialJunk2);
|
|
||||||
clientSpecialJunk3 = clientProtocolConfig.value(config_key::specialJunk3).toString(protocols::awg::defaultSpecialJunk3);
|
|
||||||
clientSpecialJunk4 = clientProtocolConfig.value(config_key::specialJunk4).toString(protocols::awg::defaultSpecialJunk4);
|
|
||||||
clientSpecialJunk5 = clientProtocolConfig.value(config_key::specialJunk5).toString(protocols::awg::defaultSpecialJunk5);
|
|
||||||
clientControlledJunk1 = clientProtocolConfig.value(config_key::controlledJunk1).toString(protocols::awg::defaultControlledJunk1);
|
|
||||||
clientControlledJunk2 = clientProtocolConfig.value(config_key::controlledJunk2).toString(protocols::awg::defaultControlledJunk2);
|
|
||||||
clientControlledJunk3 = clientProtocolConfig.value(config_key::controlledJunk3).toString(protocols::awg::defaultControlledJunk3);
|
|
||||||
clientSpecialHandshakeTimeout =
|
|
||||||
clientProtocolConfig.value(config_key::specialHandshakeTimeout).toString(protocols::awg::defaultSpecialHandshakeTimeout);
|
|
||||||
|
|
||||||
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
|
||||||
port = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
port = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
|
||||||
|
|
@ -301,10 +209,6 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
|
||||||
serverInitPacketJunkSize = serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
|
serverInitPacketJunkSize = serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
|
||||||
serverResponsePacketJunkSize =
|
serverResponsePacketJunkSize =
|
||||||
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
|
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
|
||||||
// serverCookieReplyPacketJunkSize =
|
|
||||||
// serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
|
|
||||||
// serverTransportPacketJunkSize =
|
|
||||||
// serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
|
|
||||||
serverInitPacketMagicHeader =
|
serverInitPacketMagicHeader =
|
||||||
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
|
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
|
||||||
serverResponsePacketMagicHeader =
|
serverResponsePacketMagicHeader =
|
||||||
|
|
@ -320,8 +224,6 @@ bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const
|
||||||
if (subnetAddress != other.subnetAddress || port != other.port || serverJunkPacketCount != other.serverJunkPacketCount
|
if (subnetAddress != other.subnetAddress || port != other.port || serverJunkPacketCount != other.serverJunkPacketCount
|
||||||
|| serverJunkPacketMinSize != other.serverJunkPacketMinSize || serverJunkPacketMaxSize != other.serverJunkPacketMaxSize
|
|| serverJunkPacketMinSize != other.serverJunkPacketMinSize || serverJunkPacketMaxSize != other.serverJunkPacketMaxSize
|
||||||
|| serverInitPacketJunkSize != other.serverInitPacketJunkSize || serverResponsePacketJunkSize != other.serverResponsePacketJunkSize
|
|| serverInitPacketJunkSize != other.serverInitPacketJunkSize || serverResponsePacketJunkSize != other.serverResponsePacketJunkSize
|
||||||
// || serverCookieReplyPacketJunkSize != other.serverCookieReplyPacketJunkSize
|
|
||||||
// || serverTransportPacketJunkSize != other.serverTransportPacketJunkSize
|
|
||||||
|| serverInitPacketMagicHeader != other.serverInitPacketMagicHeader
|
|| serverInitPacketMagicHeader != other.serverInitPacketMagicHeader
|
||||||
|| serverResponsePacketMagicHeader != other.serverResponsePacketMagicHeader
|
|| serverResponsePacketMagicHeader != other.serverResponsePacketMagicHeader
|
||||||
|| serverUnderloadPacketMagicHeader != other.serverUnderloadPacketMagicHeader
|
|| serverUnderloadPacketMagicHeader != other.serverUnderloadPacketMagicHeader
|
||||||
|
|
@ -334,12 +236,7 @@ bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const
|
||||||
bool AwgConfig::hasEqualClientSettings(const AwgConfig &other) const
|
bool AwgConfig::hasEqualClientSettings(const AwgConfig &other) const
|
||||||
{
|
{
|
||||||
if (clientMtu != other.clientMtu || clientJunkPacketCount != other.clientJunkPacketCount
|
if (clientMtu != other.clientMtu || clientJunkPacketCount != other.clientJunkPacketCount
|
||||||
|| clientJunkPacketMinSize != other.clientJunkPacketMinSize || clientJunkPacketMaxSize != other.clientJunkPacketMaxSize
|
|| clientJunkPacketMinSize != other.clientJunkPacketMinSize || clientJunkPacketMaxSize != other.clientJunkPacketMaxSize) {
|
||||||
|| clientSpecialJunk1 != other.clientSpecialJunk1 || clientSpecialJunk2 != other.clientSpecialJunk2
|
|
||||||
|| clientSpecialJunk3 != other.clientSpecialJunk3 || clientSpecialJunk4 != other.clientSpecialJunk4
|
|
||||||
|| clientSpecialJunk5 != other.clientSpecialJunk5 || clientControlledJunk1 != other.clientControlledJunk1
|
|
||||||
|| clientControlledJunk2 != other.clientControlledJunk2 || clientControlledJunk3 != other.clientControlledJunk3
|
|
||||||
|| clientSpecialHandshakeTimeout != other.clientSpecialHandshakeTimeout) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,9 @@
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
namespace AwgConstant
|
namespace AwgConstant {
|
||||||
{
|
|
||||||
const int messageInitiationSize = 148;
|
const int messageInitiationSize = 148;
|
||||||
const int messageResponseSize = 92;
|
const int messageResponseSize = 92;
|
||||||
const int messageCookieReplySize = 64;
|
|
||||||
const int messageTransportSize = 32;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AwgConfig
|
struct AwgConfig
|
||||||
|
|
@ -25,23 +22,12 @@ struct AwgConfig
|
||||||
QString clientJunkPacketCount;
|
QString clientJunkPacketCount;
|
||||||
QString clientJunkPacketMinSize;
|
QString clientJunkPacketMinSize;
|
||||||
QString clientJunkPacketMaxSize;
|
QString clientJunkPacketMaxSize;
|
||||||
QString clientSpecialJunk1;
|
|
||||||
QString clientSpecialJunk2;
|
|
||||||
QString clientSpecialJunk3;
|
|
||||||
QString clientSpecialJunk4;
|
|
||||||
QString clientSpecialJunk5;
|
|
||||||
QString clientControlledJunk1;
|
|
||||||
QString clientControlledJunk2;
|
|
||||||
QString clientControlledJunk3;
|
|
||||||
QString clientSpecialHandshakeTimeout;
|
|
||||||
|
|
||||||
QString serverJunkPacketCount;
|
QString serverJunkPacketCount;
|
||||||
QString serverJunkPacketMinSize;
|
QString serverJunkPacketMinSize;
|
||||||
QString serverJunkPacketMaxSize;
|
QString serverJunkPacketMaxSize;
|
||||||
QString serverInitPacketJunkSize;
|
QString serverInitPacketJunkSize;
|
||||||
QString serverResponsePacketJunkSize;
|
QString serverResponsePacketJunkSize;
|
||||||
QString serverCookieReplyPacketJunkSize;
|
|
||||||
QString serverTransportPacketJunkSize;
|
|
||||||
QString serverInitPacketMagicHeader;
|
QString serverInitPacketMagicHeader;
|
||||||
QString serverResponsePacketMagicHeader;
|
QString serverResponsePacketMagicHeader;
|
||||||
QString serverUnderloadPacketMagicHeader;
|
QString serverUnderloadPacketMagicHeader;
|
||||||
|
|
@ -49,6 +35,7 @@ struct AwgConfig
|
||||||
|
|
||||||
bool hasEqualServerSettings(const AwgConfig &other) const;
|
bool hasEqualServerSettings(const AwgConfig &other) const;
|
||||||
bool hasEqualClientSettings(const AwgConfig &other) const;
|
bool hasEqualClientSettings(const AwgConfig &other) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AwgConfigModel : public QAbstractListModel
|
class AwgConfigModel : public QAbstractListModel
|
||||||
|
|
@ -64,28 +51,16 @@ public:
|
||||||
ClientJunkPacketCountRole,
|
ClientJunkPacketCountRole,
|
||||||
ClientJunkPacketMinSizeRole,
|
ClientJunkPacketMinSizeRole,
|
||||||
ClientJunkPacketMaxSizeRole,
|
ClientJunkPacketMaxSizeRole,
|
||||||
ClientSpecialJunk1Role,
|
|
||||||
ClientSpecialJunk2Role,
|
|
||||||
ClientSpecialJunk3Role,
|
|
||||||
ClientSpecialJunk4Role,
|
|
||||||
ClientSpecialJunk5Role,
|
|
||||||
ClientControlledJunk1Role,
|
|
||||||
ClientControlledJunk2Role,
|
|
||||||
ClientControlledJunk3Role,
|
|
||||||
ClientSpecialHandshakeTimeoutRole,
|
|
||||||
|
|
||||||
ServerJunkPacketCountRole,
|
ServerJunkPacketCountRole,
|
||||||
ServerJunkPacketMinSizeRole,
|
ServerJunkPacketMinSizeRole,
|
||||||
ServerJunkPacketMaxSizeRole,
|
ServerJunkPacketMaxSizeRole,
|
||||||
ServerInitPacketJunkSizeRole,
|
ServerInitPacketJunkSizeRole,
|
||||||
ServerResponsePacketJunkSizeRole,
|
ServerResponsePacketJunkSizeRole,
|
||||||
ServerCookieReplyPacketJunkSizeRole,
|
|
||||||
ServerTransportPacketJunkSizeRole,
|
|
||||||
|
|
||||||
ServerInitPacketMagicHeaderRole,
|
ServerInitPacketMagicHeaderRole,
|
||||||
ServerResponsePacketMagicHeaderRole,
|
ServerResponsePacketMagicHeaderRole,
|
||||||
ServerUnderloadPacketMagicHeaderRole,
|
ServerUnderloadPacketMagicHeaderRole,
|
||||||
ServerTransportPacketMagicHeaderRole,
|
ServerTransportPacketMagicHeaderRole
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit AwgConfigModel(QObject *parent = nullptr);
|
explicit AwgConfigModel(QObject *parent = nullptr);
|
||||||
|
|
@ -100,7 +75,7 @@ public slots:
|
||||||
QJsonObject getConfig();
|
QJsonObject getConfig();
|
||||||
|
|
||||||
bool isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4);
|
bool isHeadersEqual(const QString &h1, const QString &h2, const QString &h3, const QString &h4);
|
||||||
bool isPacketSizeEqual(const int s1, const int s2/*, const int s3, const int s4*/);
|
bool isPacketSizeEqual(const int s1, const int s2);
|
||||||
|
|
||||||
bool isServerSettingsEqual();
|
bool isServerSettingsEqual();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ bool XrayConfigModel::setData(const QModelIndex &index, const QVariant &value, i
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::SiteRole: m_protocolConfig.insert(config_key::site, value.toString()); break;
|
case Roles::SiteRole: m_protocolConfig.insert(config_key::site, value.toString()); break;
|
||||||
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit dataChanged(index, index, QList { role });
|
emit dataChanged(index, index, QList { role });
|
||||||
|
|
@ -35,7 +34,6 @@ QVariant XrayConfigModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Roles::SiteRole: return m_protocolConfig.value(config_key::site).toString(protocols::xray::defaultSite);
|
case Roles::SiteRole: return m_protocolConfig.value(config_key::site).toString(protocols::xray::defaultSite);
|
||||||
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::xray::defaultPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
@ -69,7 +67,6 @@ QHash<int, QByteArray> XrayConfigModel::roleNames() const
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
roles[SiteRole] = "site";
|
roles[SiteRole] = "site";
|
||||||
roles[PortRole] = "port";
|
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@ class XrayConfigModel : public QAbstractListModel
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
SiteRole,
|
SiteRole
|
||||||
PortRole
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit XrayConfigModel(QObject *parent = nullptr);
|
explicit XrayConfigModel(QObject *parent = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@
|
||||||
#include <AmneziaVPN-Swift.h>
|
#include <AmneziaVPN-Swift.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "core/api/apiUtils.h"
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
namespace configKey
|
namespace configKey
|
||||||
|
|
@ -68,7 +66,6 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||||
} else {
|
} else {
|
||||||
server.insert(config_key::description, value.toString());
|
server.insert(config_key::description, value.toString());
|
||||||
}
|
}
|
||||||
server.insert(config_key::nameOverriddenByUser, true);
|
|
||||||
m_settings->editServer(index.row(), server);
|
m_settings->editServer(index.row(), server);
|
||||||
m_servers.replace(index.row(), server);
|
m_servers.replace(index.row(), server);
|
||||||
if (index.row() == m_defaultServerIndex) {
|
if (index.row() == m_defaultServerIndex) {
|
||||||
|
|
@ -351,25 +348,6 @@ void ServersModel::removeServer()
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServersModel::removeServer(const int serverIndex)
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
m_settings->removeServer(serverIndex);
|
|
||||||
m_servers = m_settings->serversArray();
|
|
||||||
|
|
||||||
if (m_settings->defaultServerIndex() == serverIndex) {
|
|
||||||
setDefaultServerIndex(0);
|
|
||||||
} else if (m_settings->defaultServerIndex() > serverIndex) {
|
|
||||||
setDefaultServerIndex(m_settings->defaultServerIndex() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_settings->serversCount() == 0) {
|
|
||||||
setDefaultServerIndex(-1);
|
|
||||||
}
|
|
||||||
setProcessedServerIndex(m_defaultServerIndex);
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<int, QByteArray> ServersModel::roleNames() const
|
QHash<int, QByteArray> ServersModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
|
|
@ -429,7 +407,7 @@ void ServersModel::updateDefaultServerContainersModel()
|
||||||
emit defaultServerContainersUpdated(containers);
|
emit defaultServerContainersUpdated(containers);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ServersModel::getServerConfig(const int serverIndex) const
|
QJsonObject ServersModel::getServerConfig(const int serverIndex)
|
||||||
{
|
{
|
||||||
return m_servers.at(serverIndex).toObject();
|
return m_servers.at(serverIndex).toObject();
|
||||||
}
|
}
|
||||||
|
|
@ -816,8 +794,3 @@ const QString ServersModel::getDefaultServerImagePathCollapsed()
|
||||||
}
|
}
|
||||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper());
|
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(countryCode.toUpper());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServersModel::processedServerIsPremium() const
|
|
||||||
{
|
|
||||||
return apiUtils::isPremiumServer(getServerConfig(m_processedServerIndex));
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,6 @@ public:
|
||||||
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
|
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
|
||||||
|
|
||||||
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
||||||
Q_PROPERTY(bool processedServerIsPremium READ processedServerIsPremium NOTIFY processedServerChanged)
|
|
||||||
|
|
||||||
bool processedServerIsPremium() const;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setDefaultServerIndex(const int index);
|
void setDefaultServerIndex(const int index);
|
||||||
|
|
@ -93,9 +90,8 @@ public slots:
|
||||||
void addServer(const QJsonObject &server);
|
void addServer(const QJsonObject &server);
|
||||||
void editServer(const QJsonObject &server, const int serverIndex);
|
void editServer(const QJsonObject &server, const int serverIndex);
|
||||||
void removeServer();
|
void removeServer();
|
||||||
void removeServer(const int serverIndex);
|
|
||||||
|
|
||||||
QJsonObject getServerConfig(const int serverIndex) const;
|
QJsonObject getServerConfig(const int serverIndex);
|
||||||
|
|
||||||
void reloadDefaultServerContainerConfig();
|
void reloadDefaultServerContainerConfig();
|
||||||
void updateContainerConfig(const int containerIndex, const QJsonObject config);
|
void updateContainerConfig(const int containerIndex, const QJsonObject config);
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import Style 1.0
|
|
||||||
import "../Controls2"
|
|
||||||
import "../Controls2/TextTypes"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool enabled: true
|
|
||||||
property string placeholderText: ""
|
|
||||||
property alias textField: searchField.textField
|
|
||||||
|
|
||||||
signal addClicked(string text)
|
|
||||||
signal moreClicked()
|
|
||||||
|
|
||||||
implicitWidth: 360
|
|
||||||
implicitHeight: 96
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: background
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "#0E0F12"
|
|
||||||
opacity: 0.85
|
|
||||||
z: -1
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: addSiteButton
|
|
||||||
|
|
||||||
enabled: root.enabled
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
fill: parent
|
|
||||||
topMargin: 16
|
|
||||||
leftMargin: 16
|
|
||||||
rightMargin: 16
|
|
||||||
bottomMargin: 24
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
|
||||||
id: searchField
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
rightButtonClickedOnEnter: true
|
|
||||||
|
|
||||||
textField.placeholderText: root.placeholderText
|
|
||||||
buttonImageSource: "qrc:/images/controls/plus.svg"
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
root.addClicked(textField.text)
|
|
||||||
textField.text = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageButtonType {
|
|
||||||
id: addSiteButtonImage
|
|
||||||
implicitWidth: 56
|
|
||||||
implicitHeight: 56
|
|
||||||
|
|
||||||
image: "qrc:/images/controls/more-vertical.svg"
|
|
||||||
imageColor: AmneziaStyle.color.paleGray
|
|
||||||
|
|
||||||
onClicked: root.moreClicked()
|
|
||||||
|
|
||||||
Keys.onReturnPressed: addSiteButtonImage.clicked()
|
|
||||||
Keys.onEnterPressed: addSiteButtonImage.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,194 +0,0 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import QtCore
|
|
||||||
|
|
||||||
import PageEnum 1.0
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
import "./"
|
|
||||||
import "../Controls2"
|
|
||||||
import "../Controls2/TextTypes"
|
|
||||||
import "../Config"
|
|
||||||
import "../Components"
|
|
||||||
|
|
||||||
DrawerType2 {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
expandedHeight: parent.height * 0.9
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: ApiPremV1MigrationController
|
|
||||||
|
|
||||||
function onErrorOccurred(error, goToPageHome) {
|
|
||||||
PageController.showErrorMessage(error)
|
|
||||||
root.closeTriggered()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expandedStateContent: Item {
|
|
||||||
implicitHeight: root.expandedHeight
|
|
||||||
|
|
||||||
ListViewType {
|
|
||||||
id: listView
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
model: 1 // fake model to force the ListView to be created without a model
|
|
||||||
snapMode: ListView.NoSnap
|
|
||||||
|
|
||||||
header: ColumnLayout {
|
|
||||||
width: listView.width
|
|
||||||
|
|
||||||
Header2Type {
|
|
||||||
id: header
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 20
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
headerText: qsTr("Switch to the new Amnezia Premium subscription")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: ColumnLayout {
|
|
||||||
width: listView.width
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
anchors.rightMargin: 16
|
|
||||||
|
|
||||||
ParagraphTextType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 24
|
|
||||||
Layout.bottomMargin: 24
|
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
textFormat: Text.RichText
|
|
||||||
text: {
|
|
||||||
var str = qsTr("We'll preserve all remaining days of your current subscription and give you an extra month as a thank you. ")
|
|
||||||
str += qsTr("This new subscription type will be actively developed with more locations and features added regularly. Currently available:")
|
|
||||||
str += "<ul style='margin-left: -16px;'>"
|
|
||||||
str += qsTr("<li>13 locations (with more coming soon)</li>")
|
|
||||||
str += qsTr("<li>Easier switching between countries in the app</li>")
|
|
||||||
str += qsTr("<li>Personal dashboard to manage your subscription</li>")
|
|
||||||
str += "</ul>"
|
|
||||||
str += qsTr("Old keys will be deactivated after switching.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
|
||||||
id: emailLabel
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
borderColor: AmneziaStyle.color.mutedGray
|
|
||||||
headerTextColor: AmneziaStyle.color.paleGray
|
|
||||||
|
|
||||||
headerText: qsTr("Email")
|
|
||||||
textField.placeholderText: qsTr("mail@example.com")
|
|
||||||
|
|
||||||
|
|
||||||
textField.onFocusChanged: {
|
|
||||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: ApiPremV1MigrationController
|
|
||||||
|
|
||||||
function onNoSubscriptionToMigrate() {
|
|
||||||
emailLabel.errorText = qsTr("No old format subscriptions for a given email")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CaptionTextType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 16
|
|
||||||
|
|
||||||
color: AmneziaStyle.color.mutedGray
|
|
||||||
|
|
||||||
text: qsTr("Enter the email you used for your current subscription")
|
|
||||||
}
|
|
||||||
|
|
||||||
ApiPremV1SubListDrawer {
|
|
||||||
id: apiPremV1SubListDrawer
|
|
||||||
parent: root
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
OtpCodeDrawer {
|
|
||||||
id: otpCodeDrawer
|
|
||||||
parent: root
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: yesButton
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 32
|
|
||||||
|
|
||||||
text: qsTr("Continue")
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
ApiPremV1MigrationController.getSubscriptionList(emailLabel.textField.text)
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: noButton
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
defaultColor: AmneziaStyle.color.transparent
|
|
||||||
hoveredColor: AmneziaStyle.color.translucentWhite
|
|
||||||
pressedColor: AmneziaStyle.color.sheerWhite
|
|
||||||
disabledColor: AmneziaStyle.color.mutedGray
|
|
||||||
textColor: AmneziaStyle.color.paleGray
|
|
||||||
borderWidth: 1
|
|
||||||
|
|
||||||
text: qsTr("Remind me later")
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
root.closeTriggered()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.topMargin: 32
|
|
||||||
Layout.bottomMargin: 32
|
|
||||||
implicitHeight: 32
|
|
||||||
|
|
||||||
defaultColor: "transparent"
|
|
||||||
hoveredColor: AmneziaStyle.color.translucentWhite
|
|
||||||
pressedColor: AmneziaStyle.color.sheerWhite
|
|
||||||
textColor: AmneziaStyle.color.vibrantRed
|
|
||||||
|
|
||||||
text: qsTr("Don't remind me again")
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
var headerText = qsTr("No more reminders? You can always switch to the new format in the server settings")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
ApiPremV1MigrationController.disablePremV1MigrationReminder()
|
|
||||||
root.closeTriggered()
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
import "../Controls2"
|
|
||||||
import "../Controls2/TextTypes"
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
DrawerType2 {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: ApiPremV1MigrationController
|
|
||||||
|
|
||||||
function onSubscriptionsModelChanged() {
|
|
||||||
if (ApiPremV1MigrationController.subscriptionsModel.length > 1) {
|
|
||||||
root.openTriggered()
|
|
||||||
} else {
|
|
||||||
sendMigrationCode(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendMigrationCode(index) {
|
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
ApiPremV1MigrationController.sendMigrationCode(index)
|
|
||||||
root.closeTriggered()
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
expandedHeight: parent.height * 0.9
|
|
||||||
|
|
||||||
expandedStateContent: Item {
|
|
||||||
implicitHeight: root.expandedHeight
|
|
||||||
|
|
||||||
ListViewType {
|
|
||||||
id: listView
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
model: ApiPremV1MigrationController.subscriptionsModel
|
|
||||||
|
|
||||||
header: ColumnLayout {
|
|
||||||
width: listView.width
|
|
||||||
|
|
||||||
Header2Type {
|
|
||||||
id: header
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 20
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
|
|
||||||
headerText: qsTr("Choose Subscription")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
implicitWidth: listView.width
|
|
||||||
implicitHeight: delegateContent.implicitHeight
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: delegateContent
|
|
||||||
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
LabelWithButtonType {
|
|
||||||
id: server
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
text: qsTr("Order ID: ") + modelData.id
|
|
||||||
|
|
||||||
descriptionText: qsTr("Purchase Date: ") + Qt.formatDateTime(new Date(modelData.created_at), "dd.MM.yyyy hh:mm")
|
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
|
||||||
|
|
||||||
clickedFunction: function() {
|
|
||||||
sendMigrationCode(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DividerType {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import "../Controls2"
|
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 16
|
|
||||||
|
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
|
||||||
|
|
||||||
checkEmptyText: true
|
|
||||||
}
|
|
||||||
|
|
@ -18,8 +18,7 @@ ListView {
|
||||||
property var selectedText
|
property var selectedText
|
||||||
|
|
||||||
width: rootWidth
|
width: rootWidth
|
||||||
anchors.top: parent.top
|
height: contentItem.height
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
snapMode: ListView.SnapToItem
|
snapMode: ListView.SnapToItem
|
||||||
|
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
import "../Controls2"
|
|
||||||
import "../Controls2/TextTypes"
|
|
||||||
|
|
||||||
import "../Config"
|
|
||||||
|
|
||||||
DrawerType2 {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: ApiPremV1MigrationController
|
|
||||||
|
|
||||||
function onOtpSuccessfullySent() {
|
|
||||||
root.openTriggered()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expandedHeight: parent.height * 0.6
|
|
||||||
|
|
||||||
expandedStateContent: Item {
|
|
||||||
implicitHeight: root.expandedHeight
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.leftMargin: 16
|
|
||||||
anchors.rightMargin: 16
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Header2Type {
|
|
||||||
id: header
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 20
|
|
||||||
|
|
||||||
headerText: qsTr("OTP code was sent to your email")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
|
||||||
id: otpFiled
|
|
||||||
|
|
||||||
borderColor: AmneziaStyle.color.mutedGray
|
|
||||||
headerTextColor: AmneziaStyle.color.paleGray
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 16
|
|
||||||
headerText: qsTr("OTP Code")
|
|
||||||
textField.maximumLength: 30
|
|
||||||
checkEmptyText: true
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
|
||||||
id: saveButton
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 16
|
|
||||||
|
|
||||||
text: qsTr("Continue")
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
ApiPremV1MigrationController.migrate(otpFiled.textField.text)
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
root.closeTriggered()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
@ -41,7 +39,7 @@ DrawerType2 {
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
text: root.headerText
|
text: headerText
|
||||||
}
|
}
|
||||||
|
|
||||||
ParagraphTextType {
|
ParagraphTextType {
|
||||||
|
|
@ -50,7 +48,7 @@ DrawerType2 {
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
text: root.descriptionText
|
text: descriptionText
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
|
@ -60,11 +58,11 @@ DrawerType2 {
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
text: root.yesButtonText
|
text: yesButtonText
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
if (root.yesButtonFunction && typeof root.yesButtonFunction === "function") {
|
if (yesButtonFunction && typeof yesButtonFunction === "function") {
|
||||||
root.yesButtonFunction()
|
yesButtonFunction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -82,13 +80,11 @@ DrawerType2 {
|
||||||
textColor: AmneziaStyle.color.paleGray
|
textColor: AmneziaStyle.color.paleGray
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
|
|
||||||
visible: root.noButtonText !== ""
|
text: noButtonText
|
||||||
|
|
||||||
text: root.noButtonText
|
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
if (root.noButtonFunction && typeof root.noButtonFunction === "function") {
|
if (noButtonFunction && typeof noButtonFunction === "function") {
|
||||||
root.noButtonFunction()
|
noButtonFunction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
import "TextTypes"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string headerText
|
|
||||||
property int headerTextMaximumLineCount: 2
|
|
||||||
property int headerTextElide: Qt.ElideRight
|
|
||||||
property string descriptionText
|
|
||||||
property alias headerRow: headerRow
|
|
||||||
|
|
||||||
implicitWidth: content.implicitWidth
|
|
||||||
implicitHeight: content.implicitHeight
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: content
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: headerRow
|
|
||||||
|
|
||||||
Header1TextType {
|
|
||||||
id: header
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: root.headerText
|
|
||||||
maximumLineCount: root.headerTextMaximumLineCount
|
|
||||||
elide: root.headerTextElide
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ParagraphTextType {
|
|
||||||
id: description
|
|
||||||
Layout.topMargin: 16
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: root.descriptionText
|
|
||||||
color: AmneziaStyle.color.mutedGray
|
|
||||||
visible: root.descriptionText !== ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -239,7 +239,6 @@ Item {
|
||||||
sourceComponent: root.listView
|
sourceComponent: root.listView
|
||||||
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
86
client/ui/qml/Controls2/HeaderType.qml
Normal file
86
client/ui/qml/Controls2/HeaderType.qml
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import Style 1.0
|
||||||
|
|
||||||
|
import "TextTypes"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string actionButtonImage
|
||||||
|
property var actionButtonFunction
|
||||||
|
|
||||||
|
property alias actionButton: headerActionButton
|
||||||
|
|
||||||
|
property string headerText
|
||||||
|
property int headerTextMaximumLineCount: 2
|
||||||
|
property int headerTextElide: Qt.ElideRight
|
||||||
|
|
||||||
|
property string descriptionText
|
||||||
|
|
||||||
|
implicitWidth: content.implicitWidth
|
||||||
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Header1TextType {
|
||||||
|
id: header
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: root.headerText
|
||||||
|
maximumLineCount: root.headerTextMaximumLineCount
|
||||||
|
elide: root.headerTextElide
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageButtonType {
|
||||||
|
id: headerActionButton
|
||||||
|
|
||||||
|
implicitWidth: 40
|
||||||
|
implicitHeight: 40
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
image: root.actionButtonImage
|
||||||
|
imageColor: AmneziaStyle.color.paleGray
|
||||||
|
|
||||||
|
visible: image ? true : false
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
||||||
|
actionButtonFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
id: description
|
||||||
|
|
||||||
|
Layout.topMargin: 16
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: root.descriptionText
|
||||||
|
|
||||||
|
color: AmneziaStyle.color.mutedGray
|
||||||
|
|
||||||
|
visible: root.descriptionText !== ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
||||||
|
actionButtonFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
||||||
|
actionButtonFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
BaseHeaderType {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string actionButtonImage
|
|
||||||
property var actionButtonFunction
|
|
||||||
property alias actionButton: headerActionButton
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
headerRow.children.push(headerActionButton)
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageButtonType {
|
|
||||||
id: headerActionButton
|
|
||||||
implicitWidth: 40
|
|
||||||
implicitHeight: 40
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
image: root.actionButtonImage
|
|
||||||
imageColor: AmneziaStyle.color.paleGray
|
|
||||||
visible: image ? true : false
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
|
||||||
actionButtonFunction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onEnterPressed: {
|
|
||||||
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
|
||||||
actionButtonFunction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
|
||||||
actionButtonFunction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import Style 1.0
|
|
||||||
|
|
||||||
BaseHeaderType {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var switcherFunction
|
|
||||||
property bool showSwitcher: false
|
|
||||||
property alias switcher: headerSwitcher
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
headerRow.children.push(headerSwitcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
SwitcherType {
|
|
||||||
id: headerSwitcher
|
|
||||||
Layout.alignment: Qt.AlignRight
|
|
||||||
visible: root.showSwitcher
|
|
||||||
|
|
||||||
onToggled: {
|
|
||||||
if (switcherFunction && typeof switcherFunction === "function") {
|
|
||||||
switcherFunction(checked)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -20,11 +20,7 @@ RadioButton {
|
||||||
property string selectedColor: AmneziaStyle.color.transparent
|
property string selectedColor: AmneziaStyle.color.transparent
|
||||||
|
|
||||||
property string textColor: AmneziaStyle.color.paleGray
|
property string textColor: AmneziaStyle.color.paleGray
|
||||||
property string textDisabledColor: AmneziaStyle.color.mutedGray
|
|
||||||
property string selectedTextColor: AmneziaStyle.color.goldenApricot
|
property string selectedTextColor: AmneziaStyle.color.goldenApricot
|
||||||
property string selectedTextDisabledColor: AmneziaStyle.color.burntOrange
|
|
||||||
property string descriptionColor: AmneziaStyle.color.mutedGray
|
|
||||||
property string descriptionDisabledColor: AmneziaStyle.color.charcoalGray
|
|
||||||
|
|
||||||
property string borderFocusedColor: AmneziaStyle.color.paleGray
|
property string borderFocusedColor: AmneziaStyle.color.paleGray
|
||||||
property int borderFocusedWidth: 1
|
property int borderFocusedWidth: 1
|
||||||
|
|
@ -34,12 +30,6 @@ RadioButton {
|
||||||
|
|
||||||
property bool isFocusable: true
|
property bool isFocusable: true
|
||||||
|
|
||||||
|
|
||||||
property string radioButtonInnerCirclePressedSource: "qrc:/images/controls/radio-button-inner-circle-pressed.png"
|
|
||||||
property string radioButtonInnerCircleSource: "qrc:/images/controls/radio-button-inner-circle.png"
|
|
||||||
property string radioButtonPressedSource: "qrc:/images/controls/radio-button-pressed.svg"
|
|
||||||
property string radioButtonDefaultSource: "qrc:/images/controls/radio-button.svg"
|
|
||||||
|
|
||||||
Keys.onTabPressed: {
|
Keys.onTabPressed: {
|
||||||
FocusController.nextKeyTabItem()
|
FocusController.nextKeyTabItem()
|
||||||
}
|
}
|
||||||
|
|
@ -104,15 +94,14 @@ RadioButton {
|
||||||
if (showImage) {
|
if (showImage) {
|
||||||
return imageSource
|
return imageSource
|
||||||
} else if (root.pressed) {
|
} else if (root.pressed) {
|
||||||
return root.radioButtonInnerCirclePressedSource
|
return "qrc:/images/controls/radio-button-inner-circle-pressed.png"
|
||||||
} else if (root.checked) {
|
} else if (root.checked) {
|
||||||
return root.radioButtonInnerCircleSource
|
return "qrc:/images/controls/radio-button-inner-circle.png"
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
opacity: root.enabled ? 1.0 : 0.3
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
width: 24
|
width: 24
|
||||||
|
|
@ -124,13 +113,12 @@ RadioButton {
|
||||||
if (showImage) {
|
if (showImage) {
|
||||||
return ""
|
return ""
|
||||||
} else if (root.pressed || root.checked) {
|
} else if (root.pressed || root.checked) {
|
||||||
return root.radioButtonPressedSource
|
return "qrc:/images/controls/radio-button-pressed.svg"
|
||||||
} else {
|
} else {
|
||||||
return root.radioButtonDefaultSource
|
return "qrc:/images/controls/radio-button.svg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opacity: root.enabled ? 1.0 : 0.3
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
width: 24
|
width: 24
|
||||||
|
|
@ -160,11 +148,10 @@ RadioButton {
|
||||||
elide: root.textElide
|
elide: root.textElide
|
||||||
|
|
||||||
color: {
|
color: {
|
||||||
if (root.enabled) {
|
if (root.checked) {
|
||||||
return root.checked ? selectedTextColor : textColor
|
return selectedTextColor
|
||||||
} else {
|
|
||||||
return root.checked ? selectedTextDisabledColor : textDisabledColor
|
|
||||||
}
|
}
|
||||||
|
return textColor
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -177,7 +164,7 @@ RadioButton {
|
||||||
CaptionTextType {
|
CaptionTextType {
|
||||||
id: description
|
id: description
|
||||||
|
|
||||||
color: root.enabled ? root.descriptionColor : root.descriptionDisabledColor
|
color: AmneziaStyle.color.mutedGray
|
||||||
text: root.descriptionText
|
text: root.descriptionText
|
||||||
|
|
||||||
visible: root.descriptionText !== ""
|
visible: root.descriptionText !== ""
|
||||||
|
|
@ -190,7 +177,6 @@ RadioButton {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: root
|
anchors.fill: root
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
preventStealing: false
|
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ PageType {
|
||||||
anchors.rightMargin: 16
|
anchors.rightMargin: 16
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
|
||||||
BaseHeaderType {
|
HeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ PageType {
|
||||||
header: ColumnLayout {
|
header: ColumnLayout {
|
||||||
width: listView.width
|
width: listView.width
|
||||||
|
|
||||||
BaseHeaderType {
|
HeaderType {
|
||||||
id: header
|
id: header
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
||||||
|
|
@ -33,31 +33,6 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
|
|
||||||
target: ApiPremV1MigrationController
|
|
||||||
|
|
||||||
function onMigrationFinished() {
|
|
||||||
apiPremV1MigrationDrawer.closeTriggered()
|
|
||||||
|
|
||||||
var headerText = qsTr("You've successfully switched to the new Amnezia Premium subscription!")
|
|
||||||
var descriptionText = qsTr("Old keys will no longer work. Please use your new subscription key to connect. \nThank you for staying with us!")
|
|
||||||
var yesButtonText = qsTr("Continue")
|
|
||||||
var noButtonText = ""
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
}
|
|
||||||
var noButtonFunction = function() {
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
|
||||||
|
|
||||||
function onShowMigrationDrawer() {
|
|
||||||
apiPremV1MigrationDrawer.openTriggered()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
objectName: "homeColumnItem"
|
objectName: "homeColumnItem"
|
||||||
|
|
||||||
|
|
@ -454,9 +429,4 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApiPremV1MigrationDrawer {
|
|
||||||
id: apiPremV1MigrationDrawer
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ PageType {
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
BaseHeaderType {
|
HeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
headerText: qsTr("AmneziaWG settings")
|
headerText: qsTr("AmneziaWG settings")
|
||||||
|
|
@ -115,10 +115,14 @@ PageType {
|
||||||
KeyNavigation.tab: junkPacketCountTextField.textField
|
KeyNavigation.tab: junkPacketCountTextField.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: junkPacketCountTextField
|
id: junkPacketCountTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: "Jc - Junk packet count"
|
headerText: "Jc - Junk packet count"
|
||||||
textField.text: clientJunkPacketCount
|
textField.text: clientJunkPacketCount
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== clientJunkPacketCount) {
|
if (textField.text !== clientJunkPacketCount) {
|
||||||
|
|
@ -126,13 +130,19 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
|
||||||
KeyNavigation.tab: junkPacketMinSizeTextField.textField
|
KeyNavigation.tab: junkPacketMinSizeTextField.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: junkPacketMinSizeTextField
|
id: junkPacketMinSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: "Jmin - Junk packet minimum size"
|
headerText: "Jmin - Junk packet minimum size"
|
||||||
textField.text: clientJunkPacketMinSize
|
textField.text: clientJunkPacketMinSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== clientJunkPacketMinSize) {
|
if (textField.text !== clientJunkPacketMinSize) {
|
||||||
|
|
@ -140,144 +150,28 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
|
||||||
KeyNavigation.tab: junkPacketMaxSizeTextField.textField
|
KeyNavigation.tab: junkPacketMaxSizeTextField.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: junkPacketMaxSizeTextField
|
id: junkPacketMaxSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: "Jmax - Junk packet maximum size"
|
headerText: "Jmax - Junk packet maximum size"
|
||||||
textField.text: clientJunkPacketMaxSize
|
textField.text: clientJunkPacketMaxSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== clientJunkPacketMaxSize) {
|
if (textField.text !== clientJunkPacketMaxSize) {
|
||||||
clientJunkPacketMaxSize = textField.text
|
clientJunkPacketMaxSize = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
checkEmptyText: true
|
||||||
id: specialJunk1TextField
|
|
||||||
headerText: qsTr("I1 - First special junk packet")
|
|
||||||
textField.text: clientSpecialJunk1
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientSpecialJunk1) {
|
|
||||||
clientSpecialJunk1 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: specialJunk2TextField
|
|
||||||
headerText: qsTr("I2 - Second special junk packet")
|
|
||||||
textField.text: clientSpecialJunk2
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientSpecialJunk2) {
|
|
||||||
clientSpecialJunk2 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: specialJunk3TextField
|
|
||||||
headerText: qsTr("I3 - Third special junk packet")
|
|
||||||
textField.text: clientSpecialJunk3
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientSpecialJunk3) {
|
|
||||||
clientSpecialJunk3 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: specialJunk4TextField
|
|
||||||
headerText: qsTr("I4 - Fourth special junk packet")
|
|
||||||
textField.text: clientSpecialJunk4
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientSpecialJunk4) {
|
|
||||||
clientSpecialJunk4 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: specialJunk5TextField
|
|
||||||
headerText: qsTr("I5 - Fifth special junk packet")
|
|
||||||
textField.text: clientSpecialJunk5
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientSpecialJunk5 ) {
|
|
||||||
clientSpecialJunk5 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: controlledJunk1TextField
|
|
||||||
headerText: qsTr("J1 - First controlled junk packet")
|
|
||||||
textField.text: clientControlledJunk1
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientControlledJunk1) {
|
|
||||||
clientControlledJunk1 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: controlledJunk2TextField
|
|
||||||
headerText: qsTr("J2 - Second controlled junk packet")
|
|
||||||
textField.text: clientControlledJunk2
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientControlledJunk2) {
|
|
||||||
clientControlledJunk2 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: controlledJunk3TextField
|
|
||||||
headerText: qsTr("J3 - Third controlled junk packet")
|
|
||||||
textField.text: clientControlledJunk3
|
|
||||||
textField.validator: null
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientControlledJunk3) {
|
|
||||||
clientControlledJunk3 = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: iTimeTextField
|
|
||||||
headerText: qsTr("Itime - Special handshake timeout")
|
|
||||||
textField.text: clientSpecialHandshakeTimeout
|
|
||||||
checkEmptyText: false
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== clientSpecialHandshakeTimeout) {
|
|
||||||
clientSpecialHandshakeTimeout = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Header2TextType {
|
Header2TextType {
|
||||||
|
|
@ -287,78 +181,82 @@ PageType {
|
||||||
text: qsTr("Server settings")
|
text: qsTr("Server settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: portTextField
|
id: portTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 8
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
headerText: qsTr("Port")
|
headerText: qsTr("Port")
|
||||||
textField.text: port
|
textField.text: port
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: initPacketJunkSizeTextField
|
id: initPacketJunkSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
headerText: "S1 - Init packet junk size"
|
headerText: "S1 - Init packet junk size"
|
||||||
textField.text: serverInitPacketJunkSize
|
textField.text: serverInitPacketJunkSize
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: responsePacketJunkSizeTextField
|
id: responsePacketJunkSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
headerText: "S2 - Response packet junk size"
|
headerText: "S2 - Response packet junk size"
|
||||||
textField.text: serverResponsePacketJunkSize
|
textField.text: serverResponsePacketJunkSize
|
||||||
}
|
}
|
||||||
|
|
||||||
// AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
// id: cookieReplyPacketJunkSizeTextField
|
|
||||||
// enabled: false
|
|
||||||
|
|
||||||
// headerText: "S3 - Cookie Reply packet junk size"
|
|
||||||
// textField.text: serverCookieReplyPacketJunkSize
|
|
||||||
// }
|
|
||||||
|
|
||||||
// AwgTextField {
|
|
||||||
// id: transportPacketJunkSizeTextField
|
|
||||||
// enabled: false
|
|
||||||
|
|
||||||
// headerText: "S4 - Transport packet junk size"
|
|
||||||
// textField.text: serverTransportPacketJunkSize
|
|
||||||
// }
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: initPacketMagicHeaderTextField
|
id: initPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
headerText: "H1 - Init packet magic header"
|
headerText: "H1 - Init packet magic header"
|
||||||
textField.text: serverInitPacketMagicHeader
|
textField.text: serverInitPacketMagicHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: responsePacketMagicHeaderTextField
|
id: responsePacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
headerText: "H2 - Response packet magic header"
|
headerText: "H2 - Response packet magic header"
|
||||||
textField.text: serverResponsePacketMagicHeader
|
textField.text: serverResponsePacketMagicHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: underloadPacketMagicHeaderTextField
|
id: underloadPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
headerText: "H3 - Underload packet magic header"
|
headerText: "H3 - Underload packet magic header"
|
||||||
textField.text: serverUnderloadPacketMagicHeader
|
textField.text: serverUnderloadPacketMagicHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: transportPacketMagicHeaderTextField
|
id: transportPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
headerText: "H4 - Transport packet magic header"
|
headerText: "H4 - Transport packet magic header"
|
||||||
textField.text: serverTransportPacketMagicHeader
|
textField.text: serverTransportPacketMagicHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ PageType {
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
BaseHeaderType {
|
HeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
headerText: qsTr("AmneziaWG settings")
|
headerText: qsTr("AmneziaWG settings")
|
||||||
|
|
@ -138,138 +138,183 @@ PageType {
|
||||||
checkEmptyText: true
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: junkPacketCountTextField
|
id: junkPacketCountTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Jc - Junk packet count")
|
headerText: qsTr("Jc - Junk packet count")
|
||||||
textField.text: serverJunkPacketCount
|
textField.text: serverJunkPacketCount
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
|
if (textField.text === "") {
|
||||||
|
textField.text = "0"
|
||||||
|
}
|
||||||
|
|
||||||
if (textField.text !== serverJunkPacketCount) {
|
if (textField.text !== serverJunkPacketCount) {
|
||||||
serverJunkPacketCount = textField.text
|
serverJunkPacketCount = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: junkPacketMinSizeTextField
|
id: junkPacketMinSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Jmin - Junk packet minimum size")
|
headerText: qsTr("Jmin - Junk packet minimum size")
|
||||||
textField.text: serverJunkPacketMinSize
|
textField.text: serverJunkPacketMinSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== serverJunkPacketMinSize) {
|
if (textField.text !== serverJunkPacketMinSize) {
|
||||||
serverJunkPacketMinSize = textField.text
|
serverJunkPacketMinSize = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: junkPacketMaxSizeTextField
|
id: junkPacketMaxSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Jmax - Junk packet maximum size")
|
headerText: qsTr("Jmax - Junk packet maximum size")
|
||||||
textField.text: serverJunkPacketMaxSize
|
textField.text: serverJunkPacketMaxSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== serverJunkPacketMaxSize) {
|
if (textField.text !== serverJunkPacketMaxSize) {
|
||||||
serverJunkPacketMaxSize = textField.text
|
serverJunkPacketMaxSize = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: initPacketJunkSizeTextField
|
id: initPacketJunkSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("S1 - Init packet junk size")
|
headerText: qsTr("S1 - Init packet junk size")
|
||||||
textField.text: serverInitPacketJunkSize
|
textField.text: serverInitPacketJunkSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== serverInitPacketJunkSize) {
|
if (textField.text !== serverInitPacketJunkSize) {
|
||||||
serverInitPacketJunkSize = textField.text
|
serverInitPacketJunkSize = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if(activeFocus) {
|
||||||
|
listview.positionViewAtEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: responsePacketJunkSizeTextField
|
id: responsePacketJunkSizeTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("S2 - Response packet junk size")
|
headerText: qsTr("S2 - Response packet junk size")
|
||||||
textField.text: serverResponsePacketJunkSize
|
textField.text: serverResponsePacketJunkSize
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== serverResponsePacketJunkSize) {
|
if (textField.text !== serverResponsePacketJunkSize) {
|
||||||
serverResponsePacketJunkSize = textField.text
|
serverResponsePacketJunkSize = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if(activeFocus) {
|
||||||
|
listview.positionViewAtEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
// id: cookieReplyPacketJunkSizeTextField
|
|
||||||
// headerText: qsTr("S3 - Cookie reply packet junk size")
|
|
||||||
// textField.text: serverCookieReplyPacketJunkSize
|
|
||||||
|
|
||||||
// textField.onEditingFinished: {
|
|
||||||
// if (textField.text !== serverCookieReplyPacketJunkSize) {
|
|
||||||
// serverCookieReplyPacketJunkSize = textField.text
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// AwgTextField {
|
|
||||||
// id: transportPacketJunkSizeTextField
|
|
||||||
// headerText: qsTr("S4 - Transport packet junk size")
|
|
||||||
// textField.text: serverTransportPacketJunkSize
|
|
||||||
|
|
||||||
// textField.onEditingFinished: {
|
|
||||||
// if (textField.text !== serverTransportPacketJunkSize) {
|
|
||||||
// serverTransportPacketJunkSize = textField.text
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: initPacketMagicHeaderTextField
|
id: initPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("H1 - Init packet magic header")
|
headerText: qsTr("H1 - Init packet magic header")
|
||||||
textField.text: serverInitPacketMagicHeader
|
textField.text: serverInitPacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== serverInitPacketMagicHeader) {
|
if (textField.text !== serverInitPacketMagicHeader) {
|
||||||
serverInitPacketMagicHeader = textField.text
|
serverInitPacketMagicHeader = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: responsePacketMagicHeaderTextField
|
id: responsePacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("H2 - Response packet magic header")
|
headerText: qsTr("H2 - Response packet magic header")
|
||||||
textField.text: serverResponsePacketMagicHeader
|
textField.text: serverResponsePacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== serverResponsePacketMagicHeader) {
|
if (textField.text !== serverResponsePacketMagicHeader) {
|
||||||
serverResponsePacketMagicHeader = textField.text
|
serverResponsePacketMagicHeader = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
AwgTextField {
|
TextFieldWithHeaderType {
|
||||||
id: underloadPacketMagicHeaderTextField
|
|
||||||
headerText: qsTr("H3 - Underload packet magic header")
|
|
||||||
textField.text: serverUnderloadPacketMagicHeader
|
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
|
||||||
if (textField.text !== serverUnderloadPacketMagicHeader) {
|
|
||||||
serverUnderloadPacketMagicHeader = textField.text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AwgTextField {
|
|
||||||
id: transportPacketMagicHeaderTextField
|
id: transportPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("H4 - Transport packet magic header")
|
headerText: qsTr("H4 - Transport packet magic header")
|
||||||
textField.text: serverTransportPacketMagicHeader
|
textField.text: serverTransportPacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textField.text !== serverTransportPacketMagicHeader) {
|
if (textField.text !== serverTransportPacketMagicHeader) {
|
||||||
serverTransportPacketMagicHeader = textField.text
|
serverTransportPacketMagicHeader = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: underloadPacketMagicHeaderTextField
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("H3 - Underload packet magic header")
|
||||||
|
textField.text: serverUnderloadPacketMagicHeader
|
||||||
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
if (textField.text !== serverUnderloadPacketMagicHeader) {
|
||||||
|
serverUnderloadPacketMagicHeader = textField.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmptyText: true
|
||||||
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: saveRestartButton
|
id: saveRestartButton
|
||||||
|
|
@ -283,8 +328,6 @@ PageType {
|
||||||
responsePacketMagicHeaderTextField.errorText === "" &&
|
responsePacketMagicHeaderTextField.errorText === "" &&
|
||||||
initPacketMagicHeaderTextField.errorText === "" &&
|
initPacketMagicHeaderTextField.errorText === "" &&
|
||||||
responsePacketJunkSizeTextField.errorText === "" &&
|
responsePacketJunkSizeTextField.errorText === "" &&
|
||||||
// cookieReplyHeaderJunkTextField.errorText === "" &&
|
|
||||||
// transportHeaderJunkTextField.errorText === "" &&
|
|
||||||
initPacketJunkSizeTextField.errorText === "" &&
|
initPacketJunkSizeTextField.errorText === "" &&
|
||||||
junkPacketMaxSizeTextField.errorText === "" &&
|
junkPacketMaxSizeTextField.errorText === "" &&
|
||||||
junkPacketMinSizeTextField.errorText === "" &&
|
junkPacketMinSizeTextField.errorText === "" &&
|
||||||
|
|
@ -317,13 +360,6 @@ PageType {
|
||||||
PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)"))
|
PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92)"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// if (AwgConfigModel.isPacketSizeEqual(parseInt(initPacketJunkSizeTextField.textField.text),
|
|
||||||
// parseInt(responsePacketJunkSizeTextField.textField.text),
|
|
||||||
// parseInt(cookieReplyPacketJunkSizeTextField.textField.text),
|
|
||||||
// parseInt(transportPacketJunkSizeTextField.textField.text))) {
|
|
||||||
// PageController.showErrorMessage(qsTr("The value of the field S1 + message initiation size (148) must not equal S2 + message response size (92) + S3 + cookie reply size (64) + S4 + transport packet size (32)"))
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var headerText = qsTr("Save settings?")
|
var headerText = qsTr("Save settings?")
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,11 @@ PageType {
|
||||||
model: CloakConfigModel
|
model: CloakConfigModel
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
id: delegateItem
|
|
||||||
|
|
||||||
property alias trafficFromField: trafficFromField
|
|
||||||
property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
|
|
||||||
|
|
||||||
implicitWidth: listview.width
|
implicitWidth: listview.width
|
||||||
implicitHeight: col.implicitHeight
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
|
property alias trafficFromField: trafficFromField
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: col
|
id: col
|
||||||
|
|
||||||
|
|
@ -79,8 +76,9 @@ PageType {
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
BaseHeaderType {
|
HeaderType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
headerText: qsTr("Cloak settings")
|
headerText: qsTr("Cloak settings")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,8 +88,6 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
|
|
||||||
enabled: delegateItem.isEnabled
|
|
||||||
|
|
||||||
headerText: qsTr("Disguised as traffic from")
|
headerText: qsTr("Disguised as traffic from")
|
||||||
textField.text: site
|
textField.text: site
|
||||||
|
|
||||||
|
|
@ -108,8 +104,6 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkEmptyText: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
|
|
@ -118,8 +112,6 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: delegateItem.isEnabled
|
|
||||||
|
|
||||||
headerText: qsTr("Port")
|
headerText: qsTr("Port")
|
||||||
textField.text: port
|
textField.text: port
|
||||||
textField.maximumLength: 5
|
textField.maximumLength: 5
|
||||||
|
|
@ -130,8 +122,6 @@ PageType {
|
||||||
port = textField.text
|
port = textField.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkEmptyText: true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
|
|
@ -139,8 +129,6 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
enabled: delegateItem.isEnabled
|
|
||||||
|
|
||||||
descriptionText: qsTr("Cipher")
|
descriptionText: qsTr("Cipher")
|
||||||
headerText: qsTr("Cipher")
|
headerText: qsTr("Cipher")
|
||||||
|
|
||||||
|
|
@ -178,46 +166,25 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: saveButton
|
id: saveRestartButton
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
enabled: trafficFromField.errorText === "" &&
|
|
||||||
portTextField.errorText === ""
|
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
||||||
var headerText = qsTr("Save settings?")
|
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||||
var yesButtonText = qsTr("Continue")
|
return
|
||||||
var noButtonText = qsTr("Cancel")
|
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
|
||||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()) {
|
|
||||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
|
|
||||||
InstallController.updateContainer(CloakConfigModel.getConfig())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var noButtonFunction = function() {
|
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||||
if (!GC.isMobile()) {
|
InstallController.updateContainer(CloakConfigModel.getConfig())
|
||||||
saveButton.forceActiveFocus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEnterPressed: saveButton.clicked()
|
|
||||||
Keys.onReturnPressed: saveButton.clicked()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue