Merge branch 'qmake-to-cmake-migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-libssh-support
This commit is contained in:
commit
b0489aa61b
60 changed files with 945 additions and 1112 deletions
1
.github/workflows/deploy.yml
vendored
1
.github/workflows/deploy.yml
vendored
|
@ -152,7 +152,6 @@ jobs:
|
|||
export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
|
||||
export QT_IOS_BIN=$QT_BIN_DIR
|
||||
export PATH=$PATH:~/go/bin
|
||||
cd client
|
||||
mkdir build-ios
|
||||
$QT_IOS_BIN/qt-cmake . -B build-ios -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR
|
||||
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -23,6 +23,7 @@ qrc_*.cpp
|
|||
ui_*.h
|
||||
Makefile*
|
||||
*build-*
|
||||
compile_commands.json
|
||||
|
||||
# fastlane
|
||||
client/fastlane/report.xml
|
||||
|
@ -125,3 +126,4 @@ captures/
|
|||
|
||||
# Android Profiling
|
||||
*.hprof
|
||||
client/3rd/ShadowSocks/ss_ios.xcconfig
|
||||
|
|
343
.travis.yml
343
.travis.yml
|
@ -1,343 +0,0 @@
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- dev
|
||||
- /\d+\.\d+/
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- name: MacOS
|
||||
os: osx
|
||||
osx_image: xcode13.4
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
- PATH=/usr/local/opt/ccache/libexec:$PATH
|
||||
- QT_VERSION=5.15.2
|
||||
- QIF_VERSION=4.4
|
||||
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/clang_64/bin
|
||||
- QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin
|
||||
|
||||
install:
|
||||
- |
|
||||
if [ ! -f $QT_BIN_DIR/qmake ]; then \
|
||||
brew install p7zip ccache && \
|
||||
python3 -m pip install --upgrade pip && \
|
||||
python3 -m pip install -U aqtinstall requests py7zr && \
|
||||
python3 -m pip show aqtinstall && \
|
||||
python3 -m aqt install-qt mac desktop $QT_VERSION clang_64 -m all -O $HOME/Qt && \
|
||||
python3 -m aqt install-tool mac desktop tools_ifw -O $HOME/Qt ; \
|
||||
fi
|
||||
|
||||
script:
|
||||
- bash deploy/build_macos.sh
|
||||
|
||||
after_script:
|
||||
- ccache --show-stats
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token: $GH_TOKEN
|
||||
cleanup: false
|
||||
file:
|
||||
- "AmneziaVPN.dmg"
|
||||
on:
|
||||
tags: true
|
||||
branch: master
|
||||
|
||||
cache:
|
||||
- ccache
|
||||
- directories:
|
||||
- $HOME/Qt
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
|
||||
# ------------------------------------------------------
|
||||
- name: Windows_x64
|
||||
os: windows
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
- PATH=/c/Python39:/c/Python39/Scripts:$PATH
|
||||
- QT_VERSION=5.15.2
|
||||
- QIF_VERSION=4.4
|
||||
- QT_BIN_DIR="c:\\Qt\\$QT_VERSION\\msvc2019_64\\bin"
|
||||
- QIF_BIN_DIR="c:\\Qt\\Tools\\QtInstallerFramework\\${QIF_VERSION}\\bin"
|
||||
- BUILD_ARCH=64
|
||||
- MSVC_PATH_WIN="C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community"
|
||||
- MSVC_PATH="/C/Program Files (x86)/Microsoft Visual Studio/2019/Community"
|
||||
|
||||
install:
|
||||
- if [ ! -f "$MSVC_PATH/VC/Auxiliary/Build/vcvars64.bat" ]; then choco install --ignorepackagecodes --no-progress -y visualstudio2019buildtools --package-parameters "--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Component.VC.ATLMFC --includeRecommended --nocache --installPath $MSVC_PATH_WIN"; fi
|
||||
- if [ ! -f /C/Qt/$QT_VERSION/msvc2019_64/bin/qmake ]; then choco install python --version 3.9.1; fi
|
||||
- |
|
||||
if [ ! -f /C/Qt/$QT_VERSION/msvc2019_64/bin/qmake ]; then \
|
||||
python -m pip install --upgrade pip && \
|
||||
pip3 install -U aqtinstall requests py7zr && \
|
||||
pip3 show aqtinstall && \
|
||||
aqt install-qt windows desktop $QT_VERSION win64_msvc2019_64 -m all -O /C/Qt && \
|
||||
aqt install-tool windows desktop tools_ifw -O /C/Qt ; \
|
||||
fi
|
||||
- choco install ccache
|
||||
|
||||
script:
|
||||
- echo set BUILD_ARCH=$BUILD_ARCH > winbuild.bat
|
||||
- echo set QT_BIN_DIR="$QT_BIN_DIR" >> winbuild.bat
|
||||
- echo set QIF_BIN_DIR="$QIF_BIN_DIR" >> winbuild.bat
|
||||
- echo call \""%MSVC_PATH_WIN%\\VC\\Auxiliary\\Build\\vcvars${BUILD_ARCH}.bat\"" >> winbuild.bat
|
||||
- echo call \""%MSVC_PATH_WIN%\\Common7\\Tools\\VsDevCmd.bat\" -arch=amd64" >> winbuild.bat
|
||||
- echo call deploy\\build_windows.bat >> winbuild.bat
|
||||
- cmd //c winbuild.bat
|
||||
|
||||
after_script:
|
||||
- ccache --show-stats
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token: $GH_TOKEN
|
||||
cleanup: false
|
||||
file:
|
||||
- "AmneziaVPN_x64.exe"
|
||||
on:
|
||||
tags: true
|
||||
branch: master
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- /C/Qt
|
||||
- $MSVC_PATH
|
||||
|
||||
# ------------------------------------------------------
|
||||
- name: Windows_x32
|
||||
os: windows
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
- PATH=/c/Python39:/c/Python39/Scripts:$PATH
|
||||
- QT_VERSION=5.15.2
|
||||
- QIF_VERSION=4.4
|
||||
- QT_BIN_DIR="c:\\Qt\\${QT_VERSION}\\msvc2019\\bin"
|
||||
- QIF_BIN_DIR="c:\\Qt\\Tools\\QtInstallerFramework\\${QIF_VERSION}\\bin"
|
||||
- BUILD_ARCH=32
|
||||
- MSVC_PATH_WIN="C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community"
|
||||
- MSVC_PATH="/C/Program Files (x86)/Microsoft Visual Studio/2019/Community"
|
||||
|
||||
install:
|
||||
- if [ ! -f "$MSVC_PATH/VC/Auxiliary/Build/vcvars64.bat" ]; then choco install --ignorepackagecodes --no-progress -y visualstudio2019buildtools --package-parameters "--add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Component.VC.ATLMFC --includeRecommended --nocache --installPath $MSVC_PATH_WIN"; fi
|
||||
- if [ ! -f /C/Qt/$QT_VERSION/msvc2019/bin/qmake ]; then choco install python --version 3.9.1; fi
|
||||
- |
|
||||
if [ ! -f /C/Qt/$QT_VERSION/msvc2019/bin/qmake ]; then \
|
||||
python -m pip install --upgrade pip && \
|
||||
pip3 install -U aqtinstall requests py7zr && \
|
||||
pip3 show aqtinstall && \
|
||||
aqt install-qt windows desktop $QT_VERSION win32_msvc2019 -m all -O /C/Qt && \
|
||||
aqt install-tool windows desktop tools_ifw -O /C/Qt ; \
|
||||
fi
|
||||
- choco install ccache
|
||||
|
||||
script:
|
||||
- echo set BUILD_ARCH=$BUILD_ARCH > winbuild.bat
|
||||
- echo set QT_BIN_DIR="$QT_BIN_DIR" >> winbuild.bat
|
||||
- echo set QIF_BIN_DIR="$QIF_BIN_DIR" >> winbuild.bat
|
||||
- echo call \""%MSVC_PATH_WIN%\\VC\\Auxiliary\\Build\\vcvars${BUILD_ARCH}.bat\"" >> winbuild.bat
|
||||
- echo call \""%MSVC_PATH_WIN%\\Common7\\Tools\\VsDevCmd.bat\"" >> winbuild.bat
|
||||
- echo call deploy\\build_windows.bat >> winbuild.bat
|
||||
- cmd //c winbuild.bat
|
||||
|
||||
after_script:
|
||||
- ccache --show-stats
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token: $GH_TOKEN
|
||||
cleanup: false
|
||||
file:
|
||||
- "AmneziaVPN_x32.exe"
|
||||
on:
|
||||
tags: true
|
||||
branch: master
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- /C/Qt
|
||||
- $MSVC_PATH
|
||||
|
||||
# ------------------------------------------------------
|
||||
- name: Linux
|
||||
os: linux
|
||||
language: cpp
|
||||
dist: focal
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- p7zip
|
||||
- p7zip-full
|
||||
- python3
|
||||
- python3-pip
|
||||
- libgl-dev
|
||||
- mesa-common-dev
|
||||
- libpulse-dev
|
||||
- libxcb-*
|
||||
- libxkbcommon-x11-0
|
||||
|
||||
env:
|
||||
- QT_VERSION=5.15.2
|
||||
- QIF_VERSION=4.4
|
||||
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/gcc_64/bin
|
||||
- QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin
|
||||
|
||||
install:
|
||||
- |
|
||||
if [ ! -f $QT_BIN_DIR/qmake ]; then \
|
||||
python3 -m pip install --user $(whoami) --upgrade pip && \
|
||||
export PATH=$HOME/.local/bin:$PATH && \
|
||||
python3 -m pip install -U aqtinstall requests py7zr && \
|
||||
python3 -m pip show aqtinstall && \
|
||||
python3 -m aqt install-qt linux desktop $QT_VERSION gcc_64 -m all -O $HOME/Qt && \
|
||||
python3 -m aqt install-tool linux desktop tools_ifw -O $HOME/Qt ; \
|
||||
fi
|
||||
|
||||
script:
|
||||
- bash deploy/build_linux.sh
|
||||
|
||||
after_script:
|
||||
- ccache --show-stats
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token: $GH_TOKEN
|
||||
cleanup: false
|
||||
file:
|
||||
- "AmneziaVPN.bundle"
|
||||
on:
|
||||
tags: true
|
||||
branch: master
|
||||
|
||||
cache:
|
||||
- ccache
|
||||
- directories:
|
||||
- $HOME/Qt
|
||||
- $HOME/.ccache
|
||||
|
||||
# ------------------------------------------------------
|
||||
- name: Android
|
||||
os: linux
|
||||
language: cpp
|
||||
dist: focal
|
||||
env:
|
||||
- QT_VERSION=5.15.2
|
||||
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/android/bin
|
||||
- ANDROID_API_VERSION=android-21
|
||||
- ANDROID_HOME=$HOME/sdk
|
||||
- ANDROID_SDK_ROOT=$ANDROID_HOME
|
||||
- LOCAL_ANDROID_HOME=$ANDROID_HOME
|
||||
- LOCAL_ANDROID_SDK_ROOT=$ANDROID_HOME
|
||||
- NDK_VERSION=21d
|
||||
- ANDROID_NDK_PLATFORM=android-21
|
||||
- ANDROID_NDK_HOME=$HOME/android-ndk-r${NDK_VERSION}
|
||||
- ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
|
||||
- ANDROID_NDK_HOST=linux-x86_64
|
||||
- LOCAL_ANDROID_NDK_HOME=$ANDROID_NDK_HOME
|
||||
- LOCAL_ANDROID_NDK_HOST_PLATFORM=$ANDROID_NDK_HOST
|
||||
- JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
|
||||
- TERM=dumb
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- p7zip
|
||||
- python3
|
||||
- python3-pip
|
||||
- openjdk-8-jdk
|
||||
|
||||
install:
|
||||
- |
|
||||
if [ ! -f $QT_BIN_DIR/qmake ]; then \
|
||||
python3 -m pip install -U aqtinstall requests py7zr && \
|
||||
python3 -m pip show aqtinstall && \
|
||||
python3 -m aqt install-qt linux android $QT_VERSION -m all -O $HOME/Qt ; \
|
||||
fi
|
||||
|
||||
- |
|
||||
if [ ! -f $ANDROID_SDK_ROOT/tools/bin/sdkmanager ]; then \
|
||||
echo "Download Android SDK" && \
|
||||
wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip -qO $HOME/sdk.zip > /dev/null && \
|
||||
unzip -q -d $ANDROID_SDK_ROOT $HOME/sdk.zip && \
|
||||
echo "Download tools" && \
|
||||
yes | $ANDROID_SDK_ROOT/tools/bin/sdkmanager --licenses > /dev/null 2>&1 && \
|
||||
$ANDROID_SDK_ROOT/tools/bin/sdkmanager --install "cmdline-tools;latest" "platform-tools" "platforms;android-30" "build-tools;30.0.2" > /dev/null 2>&1 || exit 1 ; \
|
||||
fi
|
||||
- |
|
||||
if [ ! -f $ANDROID_NDK_ROOT/ndk-build ]; then \
|
||||
wget https://dl.google.com/android/repository/android-ndk-r${NDK_VERSION}-linux-x86_64.zip -qO $HOME/ndk.zip &&
|
||||
unzip -q -d $HOME $HOME/ndk.zip ; \
|
||||
fi
|
||||
|
||||
script:
|
||||
- bash deploy/build_android.sh
|
||||
|
||||
after_script:
|
||||
- ccache --show-stats
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
token: $GH_TOKEN
|
||||
cleanup: false
|
||||
file:
|
||||
- "AmneziaVPN.aab"
|
||||
on:
|
||||
tags: true
|
||||
branch: master
|
||||
|
||||
cache:
|
||||
- ccache
|
||||
- directories:
|
||||
- $HOME/Qt
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/
|
||||
- $HOME/.android/build-cache
|
||||
- $ANDROID_NDK_HOME
|
||||
- $ANDROID_SDK_ROOT
|
||||
|
||||
# ------------------------------------------------------
|
||||
- name: iOS
|
||||
os: osx
|
||||
osx_image: xcode13.4
|
||||
language: cpp
|
||||
|
||||
env:
|
||||
- PATH=/usr/local/opt/ccache/libexec:~/go/bin:$PATH
|
||||
- QT_VERSION=5.15.2
|
||||
- QT_BIN_DIR=$HOME/Qt/$QT_VERSION/ios/bin
|
||||
- QT_IOS_BIN=$QT_BIN_DIR
|
||||
|
||||
install:
|
||||
- |
|
||||
if [ ! -f $QT_BIN_DIR/qmake ]; then \
|
||||
brew install p7zip ccache && \
|
||||
python3 -m pip install --upgrade pip && \
|
||||
python3 -m pip install -U aqtinstall requests py7zr && \
|
||||
python3 -m pip show aqtinstall && \
|
||||
python3 -m aqt install-qt mac ios $QT_VERSION -m all -O $HOME/Qt ; \
|
||||
fi
|
||||
- brew install golang
|
||||
- go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
- gomobile init
|
||||
|
||||
script:
|
||||
- bash deploy/build_ios.sh
|
||||
|
||||
after_script:
|
||||
- ccache --show-stats
|
||||
|
||||
cache:
|
||||
- ccache
|
||||
- directories:
|
||||
- $HOME/Qt
|
||||
- $HOME/Library/Caches/Homebrew
|
||||
|
||||
before_cache:
|
||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then brew cleanup; fi
|
||||
# Cache only .git files under "/usr/local/Homebrew" so "brew update" does not take 5min every build
|
||||
- if [ "${TRAVIS_OS_NAME}" = "osx" ]; then find /usr/local/Homebrew \! -regex ".+\.git.+" -delete; fi
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# Amnezia VPN
|
||||
## _The best client for self-hosted VPN_
|
||||
|
||||
[](https://travis-ci.com/amnezia-vpn/desktop-client)
|
||||
[]
|
||||
|
||||
Amnezia is a VPN client with the key feature of deploying your own VPN server on you virtual server.
|
||||
|
||||
|
@ -87,6 +87,11 @@ Error 1
|
|||
Add a user defined variable to both AmneziaVPN and WireGuardNetworkExtension targets' build settings with
|
||||
key `PATH` and value `${PATH}/path/to/bin/folder/with/go/executable`, e.g. `${PATH}:/usr/local/go/bin`.
|
||||
|
||||
if above error still persists on you M1 Mac, then most proably you need to install arch based cmake
|
||||
```
|
||||
arch -arm64 brew install cmake
|
||||
```
|
||||
|
||||
Build might fail with "source files not found" error the first time you try it, because modern XCode build system compiles
|
||||
dependencies in parallel, and some dependencies end up being built after the ones that
|
||||
require them. In this case simply restart the build.
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
SUPPORTED_PLATFORMS = iphoneos
|
||||
TARGETED_DEVICE_FAMILY = 1,2
|
||||
|
||||
HEADER_SEARCH_PATHS = $(inherited) $(SRCROOT)/ShadowSocks
|
||||
//HEADER_SEARCH_PATHS = $(inherited) $(SRCROOT)/ShadowSocks $(SRCROOT)/ShadowSocks/libcares/include $(SRCROOT)/ShadowSocks/libev/arm64/include $(SRCROOT)/ShadowSocks/libsodium/include $(SRCROOT)/ShadowSocks/mbedtls/include $(SRCROOT)/ShadowSocks/pcre/arm64/include $(SRCROOT)/ShadowSocks/shadowsocks-libev/include
|
||||
|
||||
//CLANG_CXX_LANGUAGE_STANDARD = gnu++14
|
||||
//CLANG_CXX_LIBRARY = libc++
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// iOS-specific settings
|
||||
//
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.3
|
||||
|
||||
SDKROOT[arch=arm64] = iphoneos
|
||||
SDKROOT[arch=armv7] = iphoneos
|
||||
SDKROOT[arch=armv7s] = iphoneos
|
||||
|
||||
VALID_ARCHS[sdk=iphoneos*] = arm64
|
||||
PROJECT_TEMP_DIR = /Users/sanchez/work/vied/ios/vpn/desktop-client-bkp/client/3rd/ShadowSocks/build/ShadowSocks.build
|
||||
CONFIGURATION_BUILD_DIR = /Users/sanchez/work/vied/ios/vpn/desktop-client-bkp/client/3rd/ShadowSocks/build/Release-iphoneos
|
||||
BUILT_PRODUCTS_DIR = /Users/sanchez/work/vied/ios/vpn/desktop-client-bkp/client/3rd/ShadowSocks/build/Release-iphoneos
|
|
@ -1,9 +1,9 @@
|
|||
cmake_minimum_required(VERSION 3.23.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
project(${PROJECT} VERSION 2.0.10)
|
||||
set(BUILD_ID 2)
|
||||
set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
|
||||
project(${PROJECT} VERSION 2.1.2)
|
||||
set(BUILD_ID 1)
|
||||
SET(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.17)
|
||||
|
@ -30,8 +30,11 @@ set(LIBS ${LIBS}
|
|||
Qt6::Core5Compat
|
||||
)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
if(IOS)
|
||||
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/scripts/openvpn.sh)
|
||||
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/scripts/openvpn.sh args
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
|
||||
endif()
|
||||
|
||||
set(IS_CI ${CI})
|
||||
|
@ -43,87 +46,12 @@ if(IS_CI)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/3rd/QtSsh/src/ssh/qssh.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/3rd/QtSsh/src/botan/botan.cmake)
|
||||
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/3rd/SingleApplication/singleapplication.cmake)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/3rd/SortFilterProxyModel)
|
||||
set(LIBS ${LIBS} SortFilterProxyModel)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/3rd/qrcodegen/qrcodegen.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/3rd/QSimpleCrypto/QSimpleCrypto.cmake)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/3rd/zlib)
|
||||
if(WIN32)
|
||||
set(ZLIB_LIBRARY $<IF:$<CONFIG:Debug>,zlibd,zlib>)
|
||||
else()
|
||||
set(ZLIB_LIBRARY z)
|
||||
endif()
|
||||
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/3rd/zlib" "${CMAKE_CURRENT_BINARY_DIR}/3rd/zlib")
|
||||
link_directories(${CMAKE_CURRENT_BINARY_DIR}/3rd/zlib)
|
||||
link_libraries(${ZLIB_LIBRARY})
|
||||
|
||||
if(NOT LINUX)
|
||||
set(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/3rd/OpenSSL")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include")
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
|
||||
set(OPENSSL_LIBRARIES "ssl" "crypto")
|
||||
|
||||
set(OPENSSL_PATH "${CMAKE_CURRENT_LIST_DIR}/3rd/OpenSSL")
|
||||
if(WIN32)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/windows/x86_64/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/windows/x86_64/libcrypto.lib")
|
||||
else()
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/windows/x86/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/windows/x86/libcrypto.lib")
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/macos/x86_64/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/macos/x86_64/libcrypto.a")
|
||||
elseif(IOS)
|
||||
set(OPENSSL_CRYPTO_LIBRARY "${OPENSSL_LIBRARIES_DIR}/libcrypto.a")
|
||||
set(OPENSSL_SSL_LIBRARY "${OPENSSL_LIBRARIES_DIR}/libssl.a")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/ios/iphone/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/ios/iphone/libcrypto.a")
|
||||
endif()
|
||||
|
||||
file(COPY ${OPENSSL_LIB_SSL_PATH} ${OPENSSL_LIB_CRYPTO_PATH}
|
||||
DESTINATION ${OPENSSL_LIBRARIES_DIR})
|
||||
file(COPY "${OPENSSL_PATH}/include"
|
||||
DESTINATION ${OPENSSL_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
set(LIBS ${LIBS}
|
||||
OpenSSL::Crypto
|
||||
OpenSSL::SSL
|
||||
)
|
||||
|
||||
set(WITH_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/3rd/libssh)
|
||||
add_compile_definitions(_WINSOCKAPI_)
|
||||
set(LIBS ${LIBS} ssh)
|
||||
|
||||
set(BUILD_WITH_QT6 ON)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/3rd/qtkeychain)
|
||||
set(LIBS ${LIBS} qt6keychain)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/3rdparty.cmake)
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/QSimpleCrypto/include
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/OpenSSL/include
|
||||
${CMAKE_CURRENT_LIST_DIR}/../ipc
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/qtkeychain
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/libssh/include
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/libssh/include
|
||||
)
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
|
@ -215,7 +143,7 @@ if(WIN32)
|
|||
)
|
||||
|
||||
set(RESOURCES ${RESOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/platform_win/vpnclient.rc
|
||||
${CMAKE_CURRENT_LIST_DIR}/platforms/windows/amneziavpn.rc
|
||||
)
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
|
@ -334,6 +262,8 @@ endif()
|
|||
if(IOS)
|
||||
message("Client iOS build")
|
||||
|
||||
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
|
||||
set(LIBS ${LIBS} Qt6::ShaderTools)
|
||||
|
||||
|
@ -379,6 +309,7 @@ endif()
|
|||
if(CMAKE_OSX_SYSROOT STREQUAL "iphoneos")
|
||||
message("Building for iPhone OS")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0)
|
||||
|
||||
endif()
|
||||
|
||||
qt_add_executable(${PROJECT} ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC})
|
||||
|
@ -391,14 +322,14 @@ if(IOS)
|
|||
enable_language(OBJC)
|
||||
enable_language(OBJCXX)
|
||||
enable_language(Swift)
|
||||
include(src/cmake/osxtools.cmake)
|
||||
include(cmake/osxtools.cmake)
|
||||
# set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE)
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES XCODE_ATTRIBUTE_ENABLE_BITCODE "NO")
|
||||
set_target_properties(${PROJECT} PROPERTIES XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon")
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/Frameworks")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../Frameworks")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_LIST_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos)
|
||||
|
||||
|
||||
|
@ -418,7 +349,7 @@ if(IOS)
|
|||
set_target_properties(${PROJECT} PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
|
||||
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_SOURCE_DIR}/platforms/ios/WireGuard-Bridging-Header.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_LIST_DIR}/platforms/ios/WireGuard-Bridging-Header.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
|
||||
XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "AmneziaVPN-Swift.h"
|
||||
|
@ -427,7 +358,7 @@ if(IOS)
|
|||
set_target_properties(${PROJECT} PROPERTIES
|
||||
OUTPUT_NAME "AmneziaVPN"
|
||||
MACOSX_BUNDLE ON
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/ios/app/Info.plist.in
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_LIST_DIR}/ios/app/Info.plist.in
|
||||
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${BUILD_ID}"
|
||||
MACOSX_BUNDLE_COPYRIGHT "MPL-2.0"
|
||||
|
@ -436,12 +367,14 @@ if(IOS)
|
|||
MACOSX_BUNDLE_LONG_VERSION_STRING "${CMAKE_PROJECT_VERSION}-${BUILD_ID}"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${CMAKE_PROJECT_VERSION}"
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_LIST_DIR}/ios/app/main.entitlements"
|
||||
XCODE_ATTRIBUTE_MARKETING_VERSION "${CMAKE_PROJECT_VERSION}"
|
||||
XCODE_GENERATE_SCHEME TRUE
|
||||
MACOSX_BUNDLE_ICON_FILE "AppIcon"
|
||||
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT} PRIVATE ${CMAKE_SOURCE_DIR})
|
||||
target_include_directories(${PROJECT} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
target_compile_options(${PROJECT} PRIVATE
|
||||
-DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\"
|
||||
|
@ -450,20 +383,20 @@ if(IOS)
|
|||
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/Shared/Keychain.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/IPAddressRange.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/InterfaceConfiguration.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/TunnelConfiguration.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/Endpoint.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/Shared/Model/String+ArrayConversion.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/PeerConfiguration.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/DNSServer.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardApp/LocalizationHelper.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/Shared/FileManager+Extension.swift
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKitC/x25519.c
|
||||
${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/PrivateKey.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/Shared/Keychain.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/IPAddressRange.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/InterfaceConfiguration.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/TunnelConfiguration.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/Endpoint.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/Shared/Model/String+ArrayConversion.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/PeerConfiguration.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/DNSServer.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardApp/LocalizationHelper.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/Shared/FileManager+Extension.swift
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKitC/x25519.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/3rd/wireguard-apple/Sources/WireGuardKit/PrivateKey.swift
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
|
@ -472,29 +405,33 @@ if(IOS)
|
|||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/ios/app/launch.png
|
||||
${CMAKE_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_LIST_DIR}/ios/app/launch.png
|
||||
${CMAKE_CURRENT_LIST_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
)
|
||||
set_source_files_properties(
|
||||
${CMAKE_SOURCE_DIR}/ios/app/launch.png
|
||||
${CMAKE_SOURCE_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
${CMAKE_CURRENT_LIST_DIR}/ios/app/launch.png
|
||||
${CMAKE_CURRENT_LIST_DIR}/ios/app/AmneziaVPNLaunchScreen.storyboard
|
||||
PROPERTIES MACOSX_PACKAGE_LOCATION "Resources"
|
||||
)
|
||||
|
||||
target_sources(${PROJECT} PRIVATE ${CMAKE_SOURCE_DIR}/ios/Media.xcassets)
|
||||
set_source_files_properties(Media.xcassets PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
target_sources(${PROJECT} PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}/ios/Media.xcassets
|
||||
|
||||
)
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_LIST_DIR}/ios/Media.xcassets
|
||||
PROPERTIES MACOSX_PACKAGE_LOCATION "Resources"
|
||||
)
|
||||
|
||||
add_subdirectory(ios/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
set_target_properties(${PROJECT} PROPERTIES XCODE_EMBED_APP_EXTENSIONS networkextension)
|
||||
|
||||
set_property(TARGET "networkextension" PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_LIST_DIR}/3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNAdapter.framework"
|
||||
)
|
||||
set_target_properties(networkextension PROPERTIES XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON)
|
||||
set_target_properties(networkextension PROPERTIES XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION)
|
||||
set_target_properties(${PROJECT} PROPERTIES XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY ON)
|
||||
set_target_properties(${PROJECT} PROPERTIES XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION)
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
|
@ -509,9 +446,19 @@ if(ANDROID)
|
|||
${CMAKE_CURRENT_LIST_DIR}/android/gradlew.bat
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/gradle.properties
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/res/values/libs.xml
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/OpenVPNThreadv3.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/VpnService.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/VpnServiceBinder.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/res/xml/fileprovider.xml
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/AuthHelper.java
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/IPCContract.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/NotificationUtil.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/OpenVPNThreadv3.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/Prefs.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/VpnLogger.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/VpnService.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/VpnServiceBinder.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/qt/AmneziaApp.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/qt/PackageManagerHelper.java
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/qt/VPNActivity.kt
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/qt/VPNApplication.java
|
||||
${CMAKE_CURRENT_LIST_DIR}/android/src/org/amnezia/vpn/qt/VPNPermissionHelper.kt
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
@ -563,6 +510,7 @@ elseif(APPLE AND NOT IOS)
|
|||
set(DEPLOY_ARTIFACT_PATH "macos")
|
||||
endif()
|
||||
|
||||
if(NOT IOS)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
|
@ -570,3 +518,4 @@ add_custom_command(
|
|||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<?xml version="1.0"?>
|
||||
<manifest package="org.amnezia.vpn" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:installLocation="auto">
|
||||
<manifest
|
||||
package="org.amnezia.vpn"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionName="-- %%INSERT_VERSION_NAME%% --"
|
||||
android:versionCode="-- %%INSERT_VERSION_CODE%% --"
|
||||
android:installLocation="auto">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
|
@ -18,12 +23,72 @@
|
|||
|
||||
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||
|
||||
<application android:name=".qt.AmneziaApp" android:hardwareAccelerated="true" android:label="-- %%INSERT_APP_NAME%% --" android:extractNativeLibs="true" android:icon="@drawable/icon">
|
||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name=".qt.VPNActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleInstance" android:taskAffinity="" android:theme="@style/splashScreenTheme">
|
||||
<application
|
||||
android:name=".qt.AmneziaApp"
|
||||
android:hardwareAccelerated="true"
|
||||
android:label="-- %%INSERT_APP_NAME%% --"
|
||||
android:extractNativeLibs="true"
|
||||
android:icon="@drawable/icon">
|
||||
|
||||
<activity
|
||||
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
|
||||
android:name=".qt.VPNActivity"
|
||||
android:label="-- %%INSERT_APP_NAME%% --"
|
||||
android:screenOrientation="unspecified"
|
||||
android:launchMode="singleInstance"
|
||||
android:taskAffinity=""
|
||||
android:theme="@style/splashScreenTheme">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="AmneziaVPN">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:mimeType= "*/*"/>
|
||||
<data android:host="*"/>
|
||||
<data android:pathPattern=".*\\.vpn"/>
|
||||
<data android:pathPattern=".*\\..*\\.vpn"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\.vpn"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.vpn"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.vpn"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="AmneziaVPN">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:mimeType= "*/*"/>
|
||||
<data android:host="*"/>
|
||||
<data android:pathPattern=".*\\.cfg"/>
|
||||
<data android:pathPattern=".*\\..*\\.cfg"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\.cfg"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.cfg"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.cfg"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:label="AmneziaVPN">
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:mimeType= "*/*"/>
|
||||
<data android:host="*"/>
|
||||
<data android:pathPattern=".*\\.conf"/>
|
||||
<data android:pathPattern=".*\\..*\\.conf"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\.conf"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.conf"/>
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.conf"/>
|
||||
</intent-filter>
|
||||
|
||||
<!-- Application arguments -->
|
||||
<!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
|
||||
<!-- Application arguments -->
|
||||
|
@ -79,10 +144,17 @@
|
|||
<!-- extract android style -->
|
||||
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splashscreen"/>
|
||||
</activity>
|
||||
<service android:name=".VPNService" android:permission="android.permission.BIND_VPN_SERVICE" android:process=":QtOnlyProcess">
|
||||
|
||||
<service
|
||||
android:name=".VPNService"
|
||||
android:permission="android.permission.BIND_VPN_SERVICE"
|
||||
android:process=":QtOnlyProcess"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.net.VpnService"/>
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||
|
@ -95,10 +167,24 @@
|
|||
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
|
||||
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
|
||||
</service>
|
||||
<service android:name="org.amnezia.vpn.qt.VPNPermissionHelper" android:permission="android.permission.BIND_VPN_SERVICE">
|
||||
|
||||
<service
|
||||
android:name=".qt.VPNPermissionHelper"
|
||||
android:permission="android.permission.BIND_VPN_SERVICE"
|
||||
android:exported="true">
|
||||
|
||||
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
|
||||
</service>
|
||||
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="org.amnezia.vpn.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/fileprovider"/>
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
4
client/android/res/xml/fileprovider.xml
Normal file
4
client/android/res/xml/fileprovider.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<cache-path name="cache" path="/" />
|
||||
</paths>
|
5
client/android/src/org/amnezia/vpn/IPCContract.kt
Normal file
5
client/android/src/org/amnezia/vpn/IPCContract.kt
Normal file
|
@ -0,0 +1,5 @@
|
|||
package org.amnezia.vpn
|
||||
|
||||
const val IMPORT_COMMAND_CODE = 1
|
||||
const val IMPORT_ACTION_CODE = "import_action"
|
||||
const val IMPORT_CONFIG_KEY = "CONFIG_DATA_KEY"
|
|
@ -15,6 +15,8 @@ import android.os.*
|
|||
import android.system.ErrnoException
|
||||
import android.system.Os
|
||||
import android.system.OsConstants
|
||||
import android.text.TextUtils
|
||||
import androidx.core.content.FileProvider
|
||||
import com.wireguard.android.util.SharedLibraryLoader
|
||||
import com.wireguard.config.*
|
||||
import com.wireguard.crypto.Key
|
||||
|
@ -151,6 +153,31 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
|||
private var flags = 0
|
||||
private var startId = 0
|
||||
|
||||
private lateinit var mMessenger: Messenger
|
||||
|
||||
internal class ExternalConfigImportHandler(
|
||||
context: Context,
|
||||
private val serviceBinder: VPNServiceBinder,
|
||||
private val applicationContext: Context = context.applicationContext
|
||||
) : Handler() {
|
||||
|
||||
override fun handleMessage(msg: Message) {
|
||||
when (msg.what) {
|
||||
IMPORT_COMMAND_CODE -> {
|
||||
val data = msg.data.getString(IMPORT_CONFIG_KEY)
|
||||
|
||||
if (data != null) {
|
||||
serviceBinder.importConfig(data)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
super.handleMessage(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun init() {
|
||||
if (mAlreadyInitialised) {
|
||||
return
|
||||
|
@ -188,6 +215,14 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
|||
*/
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
Log.v(tag, "Aman: onBind....................")
|
||||
|
||||
if (intent.action != null && intent.action == IMPORT_ACTION_CODE) {
|
||||
Log.v(tag, "Service bind for import of config")
|
||||
mMessenger = Messenger(ExternalConfigImportHandler(this, mBinder))
|
||||
return mMessenger.binder
|
||||
}
|
||||
|
||||
Log.v(tag, "Regular service bind")
|
||||
when (mProtocol) {
|
||||
"shadowsocks" -> {
|
||||
when (intent.action) {
|
||||
|
@ -840,4 +875,44 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
|||
override fun close() = Os.close(fd)
|
||||
}
|
||||
|
||||
fun saveAsFile(configContent: String?, suggestedFileName: String): String {
|
||||
val rootDirPath = cacheDir.absolutePath
|
||||
val rootDir = File(rootDirPath)
|
||||
|
||||
if (!rootDir.exists()) {
|
||||
rootDir.mkdirs()
|
||||
}
|
||||
|
||||
val fileName = if (!TextUtils.isEmpty(suggestedFileName)) suggestedFileName else "amnezia.cfg"
|
||||
|
||||
val file = File(rootDir, fileName)
|
||||
|
||||
try {
|
||||
file.bufferedWriter().use { out -> out.write(configContent) }
|
||||
return file.toString()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
fun shareFile(attachmentFile: String?) {
|
||||
try {
|
||||
val intent = Intent(Intent.ACTION_SEND)
|
||||
intent.type = "text/*"
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
|
||||
val file = File(attachmentFile)
|
||||
val uri = FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.fileprovider", file)
|
||||
intent.putExtra(Intent.EXTRA_STREAM, uri)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
|
||||
val createChooser = Intent.createChooser(intent, "Config sharing")
|
||||
createChooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(createChooser)
|
||||
} catch (e: Exception) {
|
||||
Log.i(tag, e.message.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ class VPNServiceBinder(service: VPNService) : Binder() {
|
|||
private val tag = "VPNServiceBinder"
|
||||
private var mListener: IBinder? = null
|
||||
private var mResumeConfig: JSONObject? = null
|
||||
private var mImportedConfig: String? = null
|
||||
|
||||
/**
|
||||
* The codes this Binder does accept in [onTransact]
|
||||
|
@ -31,6 +32,7 @@ class VPNServiceBinder(service: VPNService) : Binder() {
|
|||
const val resumeActivate = 7
|
||||
const val setNotificationText = 8
|
||||
const val setFallBackNotification = 9
|
||||
const val shareConfig = 10
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,101 +72,148 @@ class VPNServiceBinder(service: VPNService) : Binder() {
|
|||
return true
|
||||
}
|
||||
|
||||
ACTIONS.resumeActivate -> {
|
||||
// [data] is empty
|
||||
// Activate the current tunnel
|
||||
try {
|
||||
mResumeConfig?.let { this.mService.turnOn(it) }
|
||||
} catch (e: Exception) {
|
||||
Log.e(tag, "An Error occurred while enabling the VPN: ${e.localizedMessage}")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.deactivate -> {
|
||||
// [data] here is empty
|
||||
this.mService.turnOff()
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.registerEventListener -> {
|
||||
// [data] contains the Binder that we need to dispatch the Events
|
||||
val binder = data.readStrongBinder()
|
||||
mListener = binder
|
||||
val obj = JSONObject()
|
||||
obj.put("connected", mService.isUp)
|
||||
obj.put("time", mService.connectionTime)
|
||||
dispatchEvent(EVENTS.init, obj.toString())
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.requestStatistic -> {
|
||||
dispatchEvent(EVENTS.statisticUpdate, mService.status.toString())
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.requestGetLog -> {
|
||||
// Grabs all the Logs and dispatch new Log Event
|
||||
dispatchEvent(EVENTS.backendLogs, Log.getContent())
|
||||
return true
|
||||
}
|
||||
ACTIONS.requestCleanupLog -> {
|
||||
Log.clearFile()
|
||||
return true
|
||||
}
|
||||
ACTIONS.setNotificationText -> {
|
||||
NotificationUtil.update(data)
|
||||
return true
|
||||
}
|
||||
ACTIONS.setFallBackNotification -> {
|
||||
NotificationUtil.saveFallBackMessage(data, mService)
|
||||
return true
|
||||
}
|
||||
IBinder.LAST_CALL_TRANSACTION -> {
|
||||
Log.e(tag, "The OS Requested to shut down the VPN")
|
||||
this.mService.turnOff()
|
||||
return true
|
||||
}
|
||||
|
||||
else -> {
|
||||
Log.e(tag, "Received invalid bind request \t Code -> $code")
|
||||
// If we're hitting this there is probably something wrong in the client.
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an Event to all registered Binders
|
||||
* [code] the Event that happened - see [EVENTS]
|
||||
* To register an Eventhandler use [onTransact] with
|
||||
* [ACTIONS.registerEventListener]
|
||||
*/
|
||||
fun dispatchEvent(code: Int, payload: String?) {
|
||||
ACTIONS.resumeActivate -> {
|
||||
// [data] is empty
|
||||
// Activate the current tunnel
|
||||
try {
|
||||
mListener?.let {
|
||||
if (it.isBinderAlive) {
|
||||
val data = Parcel.obtain()
|
||||
data.writeByteArray(payload?.toByteArray(charset("UTF-8")))
|
||||
it.transact(code, data, Parcel.obtain(), 0)
|
||||
}
|
||||
}
|
||||
} catch (e: DeadObjectException) {
|
||||
// If the QT Process is killed (not just inactive)
|
||||
// we cant access isBinderAlive, so nothing to do here.
|
||||
mResumeConfig?.let { this.mService.turnOn(it) }
|
||||
} catch (e: Exception) {
|
||||
Log.e(tag, "An Error occurred while enabling the VPN: ${e.localizedMessage}")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* The codes we Are Using in case of [dispatchEvent]
|
||||
*/
|
||||
object EVENTS {
|
||||
const val init = 0
|
||||
const val connected = 1
|
||||
const val disconnected = 2
|
||||
const val statisticUpdate = 3
|
||||
const val backendLogs = 4
|
||||
const val activationError = 5
|
||||
ACTIONS.deactivate -> {
|
||||
// [data] here is empty
|
||||
this.mService.turnOff()
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.registerEventListener -> {
|
||||
// [data] contains the Binder that we need to dispatch the Events
|
||||
val binder = data.readStrongBinder()
|
||||
mListener = binder
|
||||
val obj = JSONObject()
|
||||
obj.put("connected", mService.isUp)
|
||||
obj.put("time", mService.connectionTime)
|
||||
dispatchEvent(EVENTS.init, obj.toString())
|
||||
|
||||
////
|
||||
if (mImportedConfig != null) {
|
||||
Log.i(tag, "register: config not null")
|
||||
dispatchEvent(EVENTS.configImport, mImportedConfig)
|
||||
mImportedConfig = null
|
||||
} else {
|
||||
Log.i(tag, "register: config is null")
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.requestStatistic -> {
|
||||
dispatchEvent(EVENTS.statisticUpdate, mService.status.toString())
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.requestGetLog -> {
|
||||
// Grabs all the Logs and dispatch new Log Event
|
||||
dispatchEvent(EVENTS.backendLogs, Log.getContent())
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.requestCleanupLog -> {
|
||||
Log.clearFile()
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.setNotificationText -> {
|
||||
NotificationUtil.update(data)
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.setFallBackNotification -> {
|
||||
NotificationUtil.saveFallBackMessage(data, mService)
|
||||
return true
|
||||
}
|
||||
|
||||
ACTIONS.shareConfig -> {
|
||||
val byteArray = data.createByteArray()
|
||||
val json = byteArray?.let { String(it) }
|
||||
val config = JSONObject(json)
|
||||
val configContent = config.getString("data")
|
||||
val suggestedName = config.getString("suggestedName")
|
||||
|
||||
val filePath = mService.saveAsFile(configContent, suggestedName)
|
||||
Log.i(tag, "save file: $filePath")
|
||||
|
||||
mService.shareFile(filePath)
|
||||
return true
|
||||
}
|
||||
|
||||
IBinder.LAST_CALL_TRANSACTION -> {
|
||||
Log.e(tag, "The OS Requested to shut down the VPN")
|
||||
this.mService.turnOff()
|
||||
return true
|
||||
}
|
||||
|
||||
else -> {
|
||||
Log.e(tag, "Received invalid bind request \t Code -> $code")
|
||||
// If we're hitting this there is probably something wrong in the client.
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an Event to all registered Binders
|
||||
* [code] the Event that happened - see [EVENTS]
|
||||
* To register an Eventhandler use [onTransact] with
|
||||
* [ACTIONS.registerEventListener]
|
||||
*/
|
||||
fun dispatchEvent(code: Int, payload: String?) {
|
||||
try {
|
||||
mListener?.let {
|
||||
if (it.isBinderAlive) {
|
||||
val data = Parcel.obtain()
|
||||
data.writeByteArray(payload?.toByteArray(charset("UTF-8")))
|
||||
it.transact(code, data, Parcel.obtain(), 0)
|
||||
}
|
||||
}
|
||||
} catch (e: DeadObjectException) {
|
||||
// If the QT Process is killed (not just inactive)
|
||||
// we cant access isBinderAlive, so nothing to do here.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The codes we Are Using in case of [dispatchEvent]
|
||||
*/
|
||||
object EVENTS {
|
||||
const val init = 0
|
||||
const val connected = 1
|
||||
const val disconnected = 2
|
||||
const val statisticUpdate = 3
|
||||
const val backendLogs = 4
|
||||
const val activationError = 5
|
||||
const val configImport = 6
|
||||
}
|
||||
|
||||
fun importConfig(config: String) {
|
||||
val obj = JSONObject()
|
||||
obj.put("config", config)
|
||||
|
||||
val resultString = obj.toString()
|
||||
|
||||
Log.i(tag, "Transact import config request")
|
||||
|
||||
if (mListener != null) {
|
||||
Log.i(tag, "binder alive")
|
||||
dispatchEvent(EVENTS.configImport, resultString)
|
||||
} else {
|
||||
Log.i(tag, "binder NOT alive")
|
||||
mImportedConfig = resultString
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.amnezia.vpn.qt;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
|
||||
public class VPNActivity extends org.qtproject.qt5.android.bindings.QtActivity {
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
// TODO finalize
|
||||
// https://github.com/mozilla-mobile/mozilla-vpn-client/blob/6acff5dd9f072380a04c3fa12e9f3c98dbdd7a26/src/platforms/android/androidvpnactivity.h
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// super.onBackPressed();
|
||||
try {
|
||||
if (!handleBackButton()) {
|
||||
// Move the activity into paused state if back button was pressed
|
||||
moveTaskToBack(true);
|
||||
// finish();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if MVPN has handled the back button
|
||||
native boolean handleBackButton();
|
||||
}
|
196
client/android/src/org/amnezia/vpn/qt/VPNActivity.kt
Normal file
196
client/android/src/org/amnezia/vpn/qt/VPNActivity.kt
Normal file
|
@ -0,0 +1,196 @@
|
|||
package org.amnezia.vpn.qt;
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ComponentName
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.*
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.amnezia.vpn.VPNService
|
||||
import org.amnezia.vpn.VPNServiceBinder
|
||||
import org.amnezia.vpn.IMPORT_COMMAND_CODE
|
||||
import org.amnezia.vpn.IMPORT_ACTION_CODE
|
||||
import org.amnezia.vpn.IMPORT_CONFIG_KEY
|
||||
import org.qtproject.qt5.android.bindings.QtActivity
|
||||
import java.io.*
|
||||
|
||||
class VPNActivity : org.qtproject.qt5.android.bindings.QtActivity() {
|
||||
|
||||
private var configString: String? = null
|
||||
private var vpnServiceBinder: Messenger? = null
|
||||
private var isBound = false
|
||||
|
||||
private val TAG = "VPNActivity"
|
||||
private val STORAGE_PERMISSION_CODE = 42
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val newIntent = intent
|
||||
val newIntentAction = newIntent.action
|
||||
|
||||
if (newIntent != null && newIntentAction != null) {
|
||||
configString = processIntent(newIntent, newIntentAction)
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onNewIntent(newIntent: Intent) {
|
||||
intent = newIntent
|
||||
|
||||
val newIntentAction = newIntent.action
|
||||
|
||||
if (newIntent != null && newIntentAction != null && newIntentAction != Intent.ACTION_MAIN) {
|
||||
if (isReadStorageAllowed()) {
|
||||
configString = processIntent(newIntent, newIntentAction)
|
||||
} else {
|
||||
requestStoragePermission()
|
||||
}
|
||||
}
|
||||
|
||||
super.onNewIntent(intent)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
if (configString != null && !isBound) {
|
||||
bindVpnService()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
if (vpnServiceBinder != null && isBound) {
|
||||
unbindService(connection)
|
||||
isBound = false
|
||||
}
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
private fun isReadStorageAllowed(): Boolean {
|
||||
val permissionStatus = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
return permissionStatus == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
private fun requestStoragePermission() {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), STORAGE_PERMISSION_CODE)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
||||
if (requestCode == STORAGE_PERMISSION_CODE) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Log.d(TAG, "Storage read permission granted")
|
||||
|
||||
if (configString != null) {
|
||||
bindVpnService()
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindVpnService() {
|
||||
try {
|
||||
val intent = Intent(this, VPNService::class.java)
|
||||
intent.action = IMPORT_ACTION_CODE
|
||||
|
||||
bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun processIntent(intent: Intent, action: String): String? {
|
||||
val scheme = intent.scheme
|
||||
|
||||
if (scheme == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (action.compareTo(Intent.ACTION_VIEW) == 0) {
|
||||
val resolver = contentResolver
|
||||
|
||||
if (scheme.compareTo(ContentResolver.SCHEME_CONTENT) == 0) {
|
||||
val uri = intent.data
|
||||
val name: String? = getContentName(resolver, uri)
|
||||
|
||||
Log.d(TAG, "Content intent detected: " + action + " : " + intent.dataString + " : " + intent.type + " : " + name)
|
||||
|
||||
val input = resolver.openInputStream(uri!!)
|
||||
|
||||
return input?.bufferedReader()?.use(BufferedReader::readText)
|
||||
} else if (scheme.compareTo(ContentResolver.SCHEME_FILE) == 0) {
|
||||
val uri = intent.data
|
||||
val name = uri!!.lastPathSegment
|
||||
|
||||
Log.d(TAG, "File intent detected: " + action + " : " + intent.dataString + " : " + intent.type + " : " + name)
|
||||
|
||||
val input = resolver.openInputStream(uri)
|
||||
|
||||
return input?.bufferedReader()?.use(BufferedReader::readText)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getContentName(resolver: ContentResolver?, uri: Uri?): String? {
|
||||
val cursor = resolver!!.query(uri!!, null, null, null, null)
|
||||
|
||||
cursor.use {
|
||||
cursor!!.moveToFirst()
|
||||
val nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
|
||||
return if (nameIndex >= 0) {
|
||||
return cursor.getString(nameIndex)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var connection: ServiceConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, binder: IBinder) {
|
||||
vpnServiceBinder = Messenger(binder)
|
||||
|
||||
if (configString != null) {
|
||||
val msg: Message = Message.obtain(null, IMPORT_COMMAND_CODE, 0, 0)
|
||||
val bundle = Bundle()
|
||||
bundle.putString(IMPORT_CONFIG_KEY, configString!!)
|
||||
msg.data = bundle
|
||||
|
||||
try {
|
||||
vpnServiceBinder?.send(msg)
|
||||
} catch (e: RemoteException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
configString = null
|
||||
}
|
||||
|
||||
isBound = true
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(className: ComponentName) {
|
||||
vpnServiceBinder = null
|
||||
isBound = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK && event.repeatCount == 0) {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
}
|
|
@ -159,8 +159,8 @@ TRANSLATIONS = \
|
|||
win32 {
|
||||
DEFINES += MVPN_WINDOWS
|
||||
|
||||
OTHER_FILES += platform_win/vpnclient.rc
|
||||
RC_FILE = platform_win/vpnclient.rc
|
||||
OTHER_FILES += platforms/windows/amneziavpn.rc
|
||||
RC_FILE = platforms/windows/amneziavpn.rc
|
||||
|
||||
HEADERS += \
|
||||
protocols/ikev2_vpn_protocol_windows.h \
|
||||
|
@ -284,9 +284,19 @@ android {
|
|||
android/gradlew.bat \
|
||||
android/gradle.properties \
|
||||
android/res/values/libs.xml \
|
||||
android/res/xml/fileprovider.xml \
|
||||
android/src/org/amnezia/vpn/AuthHelper.java \
|
||||
android/src/org/amnezia/vpn/IPCContract.kt \
|
||||
android/src/org/amnezia/vpn/NotificationUtil.kt \
|
||||
android/src/org/amnezia/vpn/OpenVPNThreadv3.kt \
|
||||
android/src/org/amnezia/vpn/Prefs.kt \
|
||||
android/src/org/amnezia/vpn/VpnLogger.kt \
|
||||
android/src/org/amnezia/vpn/VpnService.kt \
|
||||
android/src/org/amnezia/vpn/VpnServiceBinder.kt \
|
||||
android/src/org/amnezia/vpn/qt/AmneziaApp.kt \
|
||||
android/src/org/amnezia/vpn/qt/PackageManagerHelper.java \
|
||||
android/src/org/amnezia/vpn/qt/VPNActivity.kt \
|
||||
android/src/org/amnezia/vpn/qt/VPNApplication.java \
|
||||
android/src/org/amnezia/vpn/qt/VPNPermissionHelper.kt
|
||||
|
||||
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
|
||||
|
@ -322,6 +332,7 @@ ios {
|
|||
LIBS += -framework Foundation
|
||||
LIBS += -framework StoreKit
|
||||
LIBS += -framework UserNotifications
|
||||
LIBS += -framework AVFoundation
|
||||
|
||||
DEFINES += MVPN_IOS
|
||||
|
||||
|
|
81
client/cmake/3rdparty.cmake
Normal file
81
client/cmake/3rdparty.cmake
Normal file
|
@ -0,0 +1,81 @@
|
|||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||
|
||||
include(${CLIENT_ROOT_DIR}/3rd/QtSsh/src/ssh/qssh.cmake)
|
||||
include(${CLIENT_ROOT_DIR}/3rd/QtSsh/src/botan/botan.cmake)
|
||||
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
include(${CLIENT_ROOT_DIR}/3rd/SingleApplication/singleapplication.cmake)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/SortFilterProxyModel)
|
||||
set(LIBS ${LIBS} SortFilterProxyModel)
|
||||
|
||||
include(${CLIENT_ROOT_DIR}/3rd/qrcodegen/qrcodegen.cmake)
|
||||
include(${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/QSimpleCrypto.cmake)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/zlib)
|
||||
if(WIN32)
|
||||
set(ZLIB_LIBRARY $<IF:$<CONFIG:Debug>,zlibd,zlib>)
|
||||
else()
|
||||
set(ZLIB_LIBRARY z)
|
||||
endif()
|
||||
set(ZLIB_INCLUDE_DIR "${CLIENT_ROOT_DIR}/3rd/zlib" "${CMAKE_CURRENT_BINARY_DIR}/3rd/zlib")
|
||||
link_directories(${CMAKE_CURRENT_BINARY_DIR}/3rd/zlib)
|
||||
link_libraries(${ZLIB_LIBRARY})
|
||||
|
||||
if(NOT LINUX)
|
||||
set(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/3rd/OpenSSL")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include")
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
|
||||
set(OPENSSL_LIBRARIES "ssl" "crypto")
|
||||
|
||||
set(OPENSSL_PATH "${CLIENT_ROOT_DIR}/3rd/OpenSSL")
|
||||
if(WIN32)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/windows/x86_64/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/windows/x86_64/libcrypto.lib")
|
||||
else()
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/windows/x86/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/windows/x86/libcrypto.lib")
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/macos/x86_64/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/macos/x86_64/libcrypto.a")
|
||||
elseif(IOS)
|
||||
set(OPENSSL_CRYPTO_LIBRARY "${OPENSSL_LIBRARIES_DIR}/libcrypto.a")
|
||||
set(OPENSSL_SSL_LIBRARY "${OPENSSL_LIBRARIES_DIR}/libssl.a")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_PATH}/lib/ios/iphone/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_PATH}/lib/ios/iphone/libcrypto.a")
|
||||
endif()
|
||||
|
||||
file(COPY ${OPENSSL_LIB_SSL_PATH} ${OPENSSL_LIB_CRYPTO_PATH}
|
||||
DESTINATION ${OPENSSL_LIBRARIES_DIR})
|
||||
file(COPY "${OPENSSL_PATH}/include"
|
||||
DESTINATION ${OPENSSL_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
set(LIBS ${LIBS}
|
||||
OpenSSL::Crypto
|
||||
OpenSSL::SSL
|
||||
)
|
||||
|
||||
set(WITH_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/libssh)
|
||||
add_compile_definitions(_WINSOCKAPI_)
|
||||
set(LIBS ${LIBS} ssh)
|
||||
|
||||
set(BUILD_WITH_QT6 ON)
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/qtkeychain)
|
||||
set(LIBS ${LIBS} qt6keychain)
|
||||
|
||||
include_directories(
|
||||
${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/include
|
||||
${CLIENT_ROOT_DIR}/3rd/OpenSSL/include
|
||||
${CLIENT_ROOT_DIR}/3rd/libssh/include
|
||||
${CLIENT_ROOT_DIR}/3rd/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/libssh/include
|
||||
)
|
|
@ -2,6 +2,8 @@ if(NOT APPLE)
|
|||
message(FATAL_ERROR "OSX Tools are only supported on Apple targets")
|
||||
endif()
|
||||
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||
|
||||
if(CMAKE_COLOR_MAKEFILE)
|
||||
set(COMMENT_ECHO_COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --blue --bold)
|
||||
else()
|
||||
|
@ -80,7 +82,7 @@ function(osx_bundle_assetcatalog TARGET)
|
|||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
COMMENT "Bundling asset catalog"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/xcassets $<TARGET_BUNDLE_CONTENT_DIR:${TARGET}>/${XCASSETS_RESOURCE_DIR}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/scripts/macos/merge_plist.py ${XCASSETS_GEN_PLIST} -o $<TARGET_BUNDLE_CONTENT_DIR:${TARGET}>/Info.plist
|
||||
COMMAND ${CLIENT_ROOT_DIR}/scripts/macos/merge_plist.py ${XCASSETS_GEN_PLIST} -o $<TARGET_BUNDLE_CONTENT_DIR:${TARGET}>/Info.plist
|
||||
)
|
||||
|
||||
target_sources(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/xcassets/Assets.car)
|
||||
|
@ -125,7 +127,7 @@ function(osx_codesign_target TARGET)
|
|||
get_target_property(CODESIGN_ENTITLEMENTS ${TARGET} XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS)
|
||||
if(CODESIGN_ENTITLEMENTS)
|
||||
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/scripts/utils/make_template.py ${CODESIGN_ENTITLEMENTS}
|
||||
COMMAND ${CLIENT_ROOT_DIR}/scripts/utils/make_template.py ${CODESIGN_ENTITLEMENTS}
|
||||
-k PRODUCT_BUNDLE_IDENTIFIER=$<TARGET_PROPERTY:${TARGET},XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER>
|
||||
-k DEVELOPMENT_TEAM=$<TARGET_PROPERTY:${TARGET},XCODE_ATTRIBUTE_DEVELOPMENT_TEAM>
|
||||
-o ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_codesign.entitlements
|
|
@ -107,21 +107,5 @@ constexpr const char* PLATFORM_NAME =
|
|||
|
||||
constexpr const char* PLACEHOLDER_USER_DNS = "127.0.0.1";
|
||||
|
||||
#if defined(MVPN_ADJUST)
|
||||
// These are the two auto-generated token from the Adjust dashboard for the
|
||||
// "Subscription Completed" event. We have two since in the Adjust dashboard we
|
||||
// have defined two apps for iOS and Android with a event token each.
|
||||
constexpr const char* ADJUST_SUBSCRIPTION_COMPLETED =
|
||||
# if defined(MVPN_IOS)
|
||||
"jl72xm"
|
||||
# elif defined(MVPN_ANDROID)
|
||||
"o1mn9m"
|
||||
# else
|
||||
""
|
||||
# endif
|
||||
;
|
||||
#endif
|
||||
|
||||
}; // namespace Constants
|
||||
|
||||
};
|
||||
#endif // CONSTANTS_H
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>AmneziaVPN-service</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Applications/AmneziaVPN.app/Contents/MacOS/AmneziaVPN-service</string>
|
||||
</array>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Sockets</key>
|
||||
<dict>
|
||||
<key>Listeners</key>
|
||||
<dict>
|
||||
<key>SockServiceName</key>
|
||||
<string>5959</string>
|
||||
<key>SockType</key>
|
||||
<string>stream</string>
|
||||
<key>SockFamily</key>
|
||||
<string>IPv4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
Binary file not shown.
|
@ -1,35 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
APP_NAME=AmneziaVPN
|
||||
PLIST_NAME=$APP_NAME.plist
|
||||
LAUNCH_DAEMONS_PLIST_NAME=/Library/LaunchDaemons/$PLIST_NAME
|
||||
LOG_FOLDER=/var/log/$APP_NAME
|
||||
LOG_FILE="$LOG_FOLDER/post-install.log"
|
||||
APP_PATH=/Applications/$APP_NAME.app
|
||||
|
||||
if launchctl list "$APP_NAME-service" &> /dev/null; then
|
||||
launchctl unload $LAUNCH_DAEMONS_PLIST_NAME
|
||||
rm -f $LAUNCH_DAEMONS_PLIST_NAME
|
||||
fi
|
||||
|
||||
tar xzf $APP_PATH/$APP_NAME.tar.gz -C $APP_PATH
|
||||
rm -f $APP_PATH/$APP_NAME.tar.gz
|
||||
sudo chmod -R a-w $APP_PATH/
|
||||
sudo chown -R root $APP_PATH/
|
||||
sudo chgrp -R wheel $APP_PATH/
|
||||
|
||||
rm -rf $LOG_FOLDER
|
||||
mkdir -p $LOG_FOLDER
|
||||
|
||||
echo "`date` Script started" > $LOG_FILE
|
||||
|
||||
killall -9 $APP_NAME-service 2>> $LOG_FILE
|
||||
|
||||
mv -f $APP_PATH/$PLIST_NAME $LAUNCH_DAEMONS_PLIST_NAME 2>> $LOG_FILE
|
||||
chown root:wheel $LAUNCH_DAEMONS_PLIST_NAME
|
||||
launchctl load $LAUNCH_DAEMONS_PLIST_NAME
|
||||
|
||||
echo "`date` Service status: $?" >> $LOG_FILE
|
||||
echo "`date` Script finished" >> $LOG_FILE
|
||||
|
||||
#rm -- "$0"
|
|
@ -1,14 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
APP_NAME=AmneziaVPN
|
||||
PLIST_NAME=$APP_NAME.plist
|
||||
LAUNCH_DAEMONS_PLIST_NAME=/Library/LaunchDaemons/$PLIST_NAME
|
||||
|
||||
if launchctl list "$APP_NAME-service" &> /dev/null; then
|
||||
launchctl unload $LAUNCH_DAEMONS_PLIST_NAME
|
||||
rm -f $LAUNCH_DAEMONS_PLIST_NAME
|
||||
fi
|
||||
|
||||
rm -rf "$HOME/Library/Application Support/$APP_NAME"
|
||||
rm -rf /var/log/$APP_NAME
|
||||
rm -rf /Applications/$APP_NAME.app/Contents
|
Binary file not shown.
Binary file not shown.
|
@ -1,74 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Mac name-resolution updater based on @cl's script here:
|
||||
# https://blog.netnerds.net/2011/10/openvpn-update-client-dns-on-mac-os-x-using-from-the-command-line/
|
||||
# Openvpn envar parsing taken from the script in debian's openvpn package.
|
||||
# Smushed together and improved by @andrewgdotcom.
|
||||
|
||||
# Parses DHCP options from openvpn to update resolv.conf
|
||||
# To use set as 'up' and 'down' script in your openvpn *.conf:
|
||||
# up /etc/openvpn/update-resolv-conf
|
||||
# down /etc/openvpn/update-resolv-conf
|
||||
|
||||
[ "$script_type" ] || exit 0
|
||||
[ "$dev" ] || exit 0
|
||||
|
||||
PATH=$PATH:/usr/sbin/
|
||||
NMSRVRS=()
|
||||
SRCHS=()
|
||||
|
||||
# Get adapter list
|
||||
IFS=$'\n' read -d '' -ra adapters < <(networksetup -listallnetworkservices |grep -v denotes) || true
|
||||
|
||||
split_into_parts()
|
||||
{
|
||||
part1="$1"
|
||||
part2="$2"
|
||||
part3="$3"
|
||||
}
|
||||
|
||||
update_all_dns()
|
||||
{
|
||||
for adapter in "${adapters[@]}"
|
||||
do
|
||||
echo updating dns for $adapter
|
||||
# set dns server to the vpn dns server
|
||||
if [[ "${SRCHS[@]}" ]]; then
|
||||
networksetup -setsearchdomains "$adapter" "${SRCHS[@]}"
|
||||
fi
|
||||
if [[ "${NMSRVRS[@]}" ]]; then
|
||||
networksetup -setdnsservers "$adapter" "${NMSRVRS[@]}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
clear_all_dns()
|
||||
{
|
||||
for adapter in "${adapters[@]}"
|
||||
do
|
||||
echo updating dns for $adapter
|
||||
networksetup -setdnsservers "$adapter" empty
|
||||
networksetup -setsearchdomains "$adapter" empty
|
||||
done
|
||||
}
|
||||
|
||||
case "$script_type" in
|
||||
up)
|
||||
for optionvarname in ${!foreign_option_*} ; do
|
||||
option="${!optionvarname}"
|
||||
echo "$option"
|
||||
split_into_parts $option
|
||||
if [ "$part1" = "dhcp-option" ] ; then
|
||||
if [ "$part2" = "DNS" ] ; then
|
||||
NMSRVRS=(${NMSRVRS[@]} $part3)
|
||||
elif [ "$part2" = "DOMAIN" ] ; then
|
||||
SRCHS=(${SRCHS[@]} $part3)
|
||||
fi
|
||||
fi
|
||||
done
|
||||
update_all_dns
|
||||
;;
|
||||
down)
|
||||
clear_all_dns
|
||||
;;
|
||||
esac
|
|
@ -1,58 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites>
|
||||
<testsuite name="fastlane.lanes">
|
||||
|
||||
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000215">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="1: Switch to certificates lane" time="0.000162">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="2: match" time="2.707099">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="3: notification" time="0.226435">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="4: clean_build_artifacts" time="0.000648">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="5: build_app" time="259.546685">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="6: testflight" time="84.84052">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="7: get_version_number" time="0.114899">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="8: get_build_number" time="1.332216">
|
||||
|
||||
</testcase>
|
||||
|
||||
|
||||
<testcase classname="fastlane.lanes" name="9: increment_build_number" time="2.325473">
|
||||
|
||||
</testcase>
|
||||
|
||||
</testsuite>
|
||||
</testsuites>
|
|
@ -38,13 +38,15 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2</string>
|
||||
<string>7</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<false/>
|
||||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
|
|
|
@ -51,6 +51,10 @@
|
|||
<true/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
|
||||
<key>CFBundleIcons</key>
|
||||
<dict/>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict/>
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 634 KiB |
|
@ -1,5 +1,7 @@
|
|||
enable_language(Swift)
|
||||
|
||||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
|
||||
add_executable(networkextension)
|
||||
set_target_properties(networkextension PROPERTIES
|
||||
OUTPUT_NAME "AmneziaVPNNetworkExtension"
|
||||
|
@ -35,7 +37,7 @@ target_link_libraries(networkextension PRIVATE ${FW_UI_KIT})
|
|||
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
|
||||
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
|
||||
|
||||
set(WG_APPLE_SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources)
|
||||
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources)
|
||||
|
||||
target_sources(networkextension PRIVATE
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
|
||||
|
@ -57,15 +59,15 @@ target_sources(networkextension PRIVATE
|
|||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift
|
||||
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift
|
||||
${CMAKE_SOURCE_DIR}/platforms/ios/iostunnel.swift
|
||||
${CMAKE_SOURCE_DIR}/platforms/ios/iosglue.mm
|
||||
${CMAKE_SOURCE_DIR}/platforms/ios/ioslogger.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iostunnel.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/ioslogger.swift
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
|
||||
WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
|
||||
OUTPUT_VARIABLE WG_VERSION_FULL
|
||||
)
|
||||
string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1)
|
||||
|
@ -74,7 +76,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
|||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_SOURCE_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
## HACK: Build only the first architecture, this will break universal builds
|
||||
|
@ -90,13 +92,13 @@ endif()
|
|||
## TODO: The upstream makefile also makes an attempt to patch the golang runtime
|
||||
## to provide the boot-time clock instead of an uptime clock. We should probably
|
||||
## make an attempt to do the same, somehow?
|
||||
include(${CMAKE_SOURCE_DIR}/src/cmake/golang.cmake)
|
||||
include(${CLIENT_ROOT_DIR}/cmake/golang.cmake)
|
||||
if(OSXARCH STREQUAL "x86_64")
|
||||
set(GOARCH amd64)
|
||||
else()
|
||||
set(GOARCH ${FIRST_OSX_ARCHITECTURE})
|
||||
endif()
|
||||
add_go_library(libwg-go ${CMAKE_SOURCE_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo/api-apple.go
|
||||
add_go_library(libwg-go ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo/api-apple.go
|
||||
GOOS ios
|
||||
GOARCH ${GOARCH}
|
||||
CGO_CFLAGS -arch ${OSXARCH}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2</string>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
|
|
@ -19,19 +19,21 @@
|
|||
|
||||
#include "android_controller.h"
|
||||
#include "core/errorstrings.h"
|
||||
#include "ui/pages_logic/StartPageLogic.h"
|
||||
|
||||
// Binder Codes for VPNServiceBinder
|
||||
// See also - VPNServiceBinder.kt
|
||||
// Actions that are Requestable
|
||||
const int ACTION_ACTIVATE = 1;
|
||||
const int ACTION_DEACTIVATE = 2;
|
||||
const int ACTION_REGISTERLISTENER = 3;
|
||||
const int ACTION_REGISTER_LISTENER = 3;
|
||||
const int ACTION_REQUEST_STATISTIC = 4;
|
||||
const int ACTION_REQUEST_GET_LOG = 5;
|
||||
const int ACTION_REQUEST_CLEANUP_LOG = 6;
|
||||
const int ACTION_RESUME_ACTIVATE = 7;
|
||||
const int ACTION_SET_NOTIFICATION_TEXT = 8;
|
||||
const int ACTION_SET_NOTIFICATION_FALLBACK = 9;
|
||||
const int ACTION_SHARE_CONFIG = 10;
|
||||
|
||||
// Event Types that will be Dispatched after registration
|
||||
const int EVENT_INIT = 0;
|
||||
|
@ -40,6 +42,7 @@ const int EVENT_DISCONNECTED = 2;
|
|||
const int EVENT_STATISTIC_UPDATE = 3;
|
||||
const int EVENT_BACKEND_LOGS = 4;
|
||||
const int EVENT_ACTIVATION_ERROR = 5;
|
||||
const int EVENT_CONFIG_IMPORT = 6;
|
||||
|
||||
namespace {
|
||||
AndroidController* s_instance = nullptr;
|
||||
|
@ -60,10 +63,12 @@ AndroidController* AndroidController::instance() {
|
|||
return s_instance;
|
||||
}
|
||||
|
||||
bool AndroidController::initialize()
|
||||
bool AndroidController::initialize(StartPageLogic *startPageLogic)
|
||||
{
|
||||
qDebug() << "Initializing";
|
||||
|
||||
m_startPageLogic = startPageLogic;
|
||||
|
||||
// Hook in the native implementation for startActivityForResult into the JNI
|
||||
JNINativeMethod methods[]{{"startActivityForResult",
|
||||
"(Landroid/content/Intent;)V",
|
||||
|
@ -151,6 +156,16 @@ void AndroidController::setNotificationText(const QString& title,
|
|||
m_serviceBinder.transact(ACTION_SET_NOTIFICATION_TEXT, data, nullptr);
|
||||
}
|
||||
|
||||
void AndroidController::shareConfig(const QString& configContent, const QString& suggestedName) {
|
||||
QJsonObject rootObject;
|
||||
rootObject["data"] = configContent;
|
||||
rootObject["suggestedName"] = suggestedName;
|
||||
QJsonDocument doc(rootObject);
|
||||
QAndroidParcel parcel;
|
||||
parcel.writeData(doc.toJson());
|
||||
m_serviceBinder.transact(ACTION_SHARE_CONFIG, parcel, nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets fallback Notification text that should be shown in case the VPN
|
||||
* switches into the Connected state without the app open
|
||||
|
@ -190,6 +205,10 @@ void AndroidController::cleanupBackendLogs() {
|
|||
m_serviceBinder.transact(ACTION_REQUEST_CLEANUP_LOG, nullParcel, nullptr);
|
||||
}
|
||||
|
||||
void AndroidController::importConfig(const QString& data){
|
||||
m_startPageLogic->importConnectionFromCode(data);
|
||||
}
|
||||
|
||||
void AndroidController::onServiceConnected(
|
||||
const QString& name, const QAndroidBinder& serviceBinder) {
|
||||
qDebug() << "Server " + name + " connected";
|
||||
|
@ -201,7 +220,7 @@ void AndroidController::onServiceConnected(
|
|||
// Send the Service our Binder to recive incoming Events
|
||||
QAndroidParcel binderParcel;
|
||||
binderParcel.writeBinder(m_binder);
|
||||
m_serviceBinder.transact(ACTION_REGISTERLISTENER, binderParcel, nullptr);
|
||||
m_serviceBinder.transact(ACTION_REGISTER_LISTENER, binderParcel, nullptr);
|
||||
}
|
||||
|
||||
void AndroidController::onServiceDisconnected(const QString& name) {
|
||||
|
@ -282,7 +301,14 @@ bool AndroidController::VPNBinder::onTransact(int code,
|
|||
case EVENT_ACTIVATION_ERROR:
|
||||
qDebug() << "Transact: error";
|
||||
emit m_controller->connectionStateChanged(VpnProtocol::Error);
|
||||
|
||||
break;
|
||||
case EVENT_CONFIG_IMPORT:
|
||||
qDebug() << "Transact: config import";
|
||||
doc = QJsonDocument::fromJson(data.readData());
|
||||
buffer = doc.object()["config"].toString();
|
||||
qDebug() << "Transact: config string" << buffer;
|
||||
m_controller->importConfig(buffer);
|
||||
break;
|
||||
default:
|
||||
qWarning() << "Transact: Invalid!";
|
||||
break;
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
//#include <QAndroidServiceConnection>
|
||||
#include <QtCore/private/qandroidextras_p.h>
|
||||
|
||||
#include "ui/uilogic.h"
|
||||
#include "ui/pages_logic/StartPageLogic.h"
|
||||
|
||||
#include "protocols/vpnprotocol.h"
|
||||
using namespace amnezia;
|
||||
|
||||
|
||||
|
||||
class AndroidController : public QObject, public QAndroidServiceConnection
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -20,7 +22,7 @@ public:
|
|||
|
||||
virtual ~AndroidController() override = default;
|
||||
|
||||
bool initialize();
|
||||
bool initialize(StartPageLogic *startPageLogic);
|
||||
|
||||
ErrorCode start();
|
||||
void stop();
|
||||
|
@ -28,9 +30,11 @@ public:
|
|||
|
||||
void checkStatus();
|
||||
void setNotificationText(const QString& title, const QString& message, int timerSec);
|
||||
void shareConfig(const QString& data, const QString& suggestedName);
|
||||
void setFallbackConnectedNotification();
|
||||
void getBackendLogs(std::function<void(const QString&)>&& callback);
|
||||
void cleanupBackendLogs();
|
||||
void importConfig(const QString& data);
|
||||
|
||||
// from QAndroidServiceConnection
|
||||
void onServiceConnected(const QString& name, const QAndroidBinder& serviceBinder) override;
|
||||
|
@ -59,6 +63,8 @@ private:
|
|||
//Protocol m_protocol;
|
||||
QJsonObject m_vpnConfig;
|
||||
|
||||
StartPageLogic *m_startPageLogic;
|
||||
|
||||
bool m_serviceConnected = false;
|
||||
std::function<void(const QString&)> m_logCallback;
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
#include <QFile>
|
||||
|
||||
@implementation QtAppDelegate
|
||||
@implementation QtAppDelegate {
|
||||
UIView *_screen;
|
||||
}
|
||||
|
||||
+(QtAppDelegate *)sharedQtAppDelegate {
|
||||
static dispatch_once_t pred;
|
||||
|
@ -26,6 +28,13 @@
|
|||
{
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
_screen = [UIScreen.mainScreen snapshotViewAfterScreenUpdates: false];
|
||||
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle: UIBlurEffectStyleDark];
|
||||
UIVisualEffectView *blurBackround = [[UIVisualEffectView alloc] initWithEffect: blurEffect];
|
||||
[_screen addSubview: blurBackround];
|
||||
blurBackround.frame = _screen.frame;
|
||||
UIWindow *_window = UIApplication.sharedApplication.keyWindow;
|
||||
[_window addSubview: _screen];
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
|
@ -44,6 +53,7 @@
|
|||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
[_screen removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
|
|
|
@ -388,7 +388,7 @@ public class IOSVpnProtocolImpl : NSObject {
|
|||
proto.providerBundleIdentifier = vpnBundleID
|
||||
|
||||
tunnel!.protocolConfiguration = proto
|
||||
tunnel!.localizedDescription = vpnName
|
||||
tunnel!.localizedDescription = "Amnezia Wireguard"
|
||||
tunnel!.isEnabled = true
|
||||
|
||||
tunnel!.saveToPreferences { [unowned self] saveError in
|
||||
|
@ -527,8 +527,9 @@ public class IOSVpnProtocolImpl : NSObject {
|
|||
@objc func checkStatus(callback: @escaping (String, String, String) -> Void) {
|
||||
Logger.global?.log(message: "Check status")
|
||||
// assert(tunnel != nil)
|
||||
|
||||
print("check status")
|
||||
let protoType = (tunnel!.localizedDescription ?? "").toTunnelType
|
||||
print(protoType);
|
||||
|
||||
switch protoType {
|
||||
case .wireguard:
|
||||
|
@ -559,7 +560,7 @@ public class IOSVpnProtocolImpl : NSObject {
|
|||
|
||||
print("server IP: \(serverIpv4Gateway)")
|
||||
|
||||
let deviceIpv4Address = getTunIPAddress()
|
||||
let deviceIpv4Address = getWiFiAddress()
|
||||
print("device IP: \(serverIpv4Gateway)")
|
||||
if deviceIpv4Address == nil {
|
||||
callback("", "", "")
|
||||
|
@ -610,8 +611,9 @@ public class IOSVpnProtocolImpl : NSObject {
|
|||
print("server IP: \(serverIpv4Gateway)")
|
||||
|
||||
|
||||
let deviceIpv4Address = getTunIPAddress()
|
||||
print("device IP: \(serverIpv4Gateway)")
|
||||
|
||||
let deviceIpv4Address = getWiFiAddress()
|
||||
print("device IP: \(deviceIpv4Address)")
|
||||
if deviceIpv4Address == nil {
|
||||
callback("", "", "")
|
||||
return
|
||||
|
@ -690,38 +692,45 @@ public class IOSVpnProtocolImpl : NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
private func getTunIPAddress() -> String? {
|
||||
var address: String? = nil
|
||||
var interfaces: UnsafeMutablePointer<ifaddrs>? = nil
|
||||
var temp_addr: UnsafeMutablePointer<ifaddrs>? = nil
|
||||
var success: Int = 0
|
||||
|
||||
// retrieve the current interfaces - returns 0 on success
|
||||
success = Int(getifaddrs(&interfaces))
|
||||
if success == 0 {
|
||||
// Loop through linked list of interfaces
|
||||
temp_addr = interfaces
|
||||
while temp_addr != nil {
|
||||
if temp_addr?.pointee.ifa_addr == nil {
|
||||
continue
|
||||
func getWiFiAddress() -> String? {
|
||||
var address : String?
|
||||
|
||||
// Get list of all interfaces on the local machine:
|
||||
var ifaddr : UnsafeMutablePointer<ifaddrs>?
|
||||
guard getifaddrs(&ifaddr) == 0 else { return nil }
|
||||
guard let firstAddr = ifaddr else { return nil }
|
||||
|
||||
// For each interface ...
|
||||
for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
|
||||
let interface = ifptr.pointee
|
||||
|
||||
// Check for IPv4 or IPv6 interface:
|
||||
let addrFamily = interface.ifa_addr.pointee.sa_family
|
||||
//if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { // **ipv6 committed
|
||||
if addrFamily == UInt8(AF_INET){
|
||||
|
||||
// Check interface name:
|
||||
let name = String(cString: interface.ifa_name)
|
||||
if name == "en0" {
|
||||
|
||||
// Convert interface address to a human readable string:
|
||||
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
|
||||
getnameinfo(interface.ifa_addr, socklen_t(interface.ifa_addr.pointee.sa_len),
|
||||
&hostname, socklen_t(hostname.count),
|
||||
nil, socklen_t(0), NI_NUMERICHOST)
|
||||
address = String(cString: hostname)
|
||||
}
|
||||
if temp_addr?.pointee.ifa_addr.pointee.sa_family == UInt8(AF_INET) {
|
||||
// Check if interface is en0 which is the wifi connection on the iPhone
|
||||
if let name = temp_addr?.pointee.ifa_name, ((String(utf8String: name)?.contains("tun")) != nil) {
|
||||
// Get NSString from C String
|
||||
if let value = temp_addr?.pointee.ifa_addr as? sockaddr_in {
|
||||
address = String(utf8String: inet_ntoa(value.sin_addr))
|
||||
}
|
||||
}
|
||||
}
|
||||
temp_addr = temp_addr?.pointee.ifa_next
|
||||
}
|
||||
}
|
||||
freeifaddrs(interfaces)
|
||||
freeifaddrs(ifaddr)
|
||||
|
||||
return address
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum TunnelType: String {
|
||||
case wireguard, openvpn, shadowsocks, empty
|
||||
}
|
||||
|
@ -729,9 +738,9 @@ enum TunnelType: String {
|
|||
extension String {
|
||||
var toTunnelType: TunnelType {
|
||||
switch self {
|
||||
case "wireguard": return .wireguard
|
||||
case "openvpn": return .openvpn
|
||||
case "shadowsocks": return .shadowsocks
|
||||
case "Amnezia Wireguard": return .wireguard
|
||||
case "Amnezia OpenVPN": return .openvpn
|
||||
case "Amnezia ShadowSocks": return .shadowsocks
|
||||
default:
|
||||
return .empty
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <windows.h>
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
IDI_ICON1 ICON "../images/app.ico"
|
||||
IDI_ICON1 ICON "../../images/app.ico"
|
||||
|
||||
#define VER_FILEVERSION 2,0,0,0
|
||||
#define VER_FILEVERSION_STR "2.0.0.0\0"
|
|
@ -10,13 +10,11 @@ fi
|
|||
RELEASE=1
|
||||
OS=
|
||||
NETWORKEXTENSION=
|
||||
ADJUST_SDK_TOKEN=
|
||||
ADJUST="CONFIG-=adjust"
|
||||
WORKINGDIR=`pwd`
|
||||
|
||||
helpFunction() {
|
||||
print G "Usage:"
|
||||
print N "\t$0 <macos|ios|> [-d|--debug] [-n|--networkextension] [-a|--adjusttoken <adjust_token>]"
|
||||
print N "\t$0 <macos|ios|> [-d|--debug] [-n|--networkextension]"
|
||||
print N ""
|
||||
print N "By default, the project is compiled in release mode. Use -d or --debug for a debug build."
|
||||
print N "Use -n or --networkextension to force the network-extension component for MacOS too."
|
||||
|
@ -26,7 +24,6 @@ helpFunction() {
|
|||
print G "Config variables:"
|
||||
print N "\tQT_MACOS_BIN=</path/of/the/qt/bin/folder/for/macos>"
|
||||
print N "\tQT_IOS_BIN=</path/of/the/qt/bin/folder/for/ios>"
|
||||
print N "\tMVPN_IOS_ADJUST_TOKEN=<token>"
|
||||
print N ""
|
||||
exit 0
|
||||
}
|
||||
|
@ -38,11 +35,6 @@ while [[ $# -gt 0 ]]; do
|
|||
key="$1"
|
||||
|
||||
case $key in
|
||||
-a | --adjusttoken)
|
||||
ADJUST_SDK_TOKEN="$2"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
-d | --debug)
|
||||
RELEASE=
|
||||
shift
|
||||
|
@ -97,11 +89,6 @@ if [[ "$OS" != "macos" ]] && [[ "$OS" != "ios" ]] && [[ "$OS" != "macostest" ]];
|
|||
helpFunction
|
||||
fi
|
||||
|
||||
if ! [[ "$ADJUST_SDK_TOKEN" ]] && [[ "$MVPN_IOS_ADJUST_TOKEN" ]]; then
|
||||
print Y "Using the MVPN_IOS_ADJUST_TOKEN value for the adjust token"
|
||||
ADJUST_SDK_TOKEN=$MVPN_IOS_ADJUST_TOKEN
|
||||
fi
|
||||
|
||||
if [[ "$OS" == "ios" ]]; then
|
||||
# Network-extension is the default for IOS
|
||||
NETWORKEXTENSION=1
|
||||
|
@ -150,7 +137,6 @@ MACOS_FLAGS="
|
|||
QTPLUGIN+=qsvg
|
||||
CONFIG-=static
|
||||
CONFIG+=balrog
|
||||
MVPN_MACOS=1
|
||||
"
|
||||
|
||||
MACOSTEST_FLAGS="
|
||||
|
@ -160,7 +146,6 @@ MACOSTEST_FLAGS="
|
|||
"
|
||||
|
||||
IOS_FLAGS="
|
||||
MVPN_IOS=1
|
||||
Q_OS_IOS=1
|
||||
"
|
||||
|
||||
|
@ -183,11 +168,6 @@ elif [ "$OS" = "macostest" ]; then
|
|||
PLATFORM=$MACOSTEST_FLAGS
|
||||
elif [ "$OS" = "ios" ]; then
|
||||
PLATFORM=$IOS_FLAGS
|
||||
if [[ "$ADJUST_SDK_TOKEN" ]]; then
|
||||
printn Y "ADJUST_SDK_TOKEN: "
|
||||
print G "$ADJUST_SDK_TOKEN"
|
||||
ADJUST="CONFIG+=adjust"
|
||||
fi
|
||||
else
|
||||
killProcess "Why are we here?"
|
||||
fi
|
||||
|
@ -249,7 +229,7 @@ else
|
|||
print Y "No Tun2Socks will be built"
|
||||
fi
|
||||
|
||||
print Y "Creating the xcode project via qmake..."
|
||||
print Y "Creating the Xcode project via qmake..."
|
||||
$QMAKE \
|
||||
VERSION=$SHORTVERSION \
|
||||
BUILD_ID=$FULLVERSION \
|
||||
|
@ -258,11 +238,10 @@ $QMAKE \
|
|||
$VPNMODE \
|
||||
$WEMODE \
|
||||
$PLATFORM \
|
||||
$ADJUST \
|
||||
./client.pro || killProcess "Compilation failed"
|
||||
|
||||
print Y "Patching the xcode project..."
|
||||
ruby scripts/xcode_patcher.rb "AmneziaVPN.xcodeproj" "$SHORTVERSION" "$FULLVERSION" "$OSRUBY" "$NETWORKEXTENSION" "$ADJUST_SDK_TOKEN" || killProcess "Failed to merge xcode with wireguard"
|
||||
ruby scripts/xcode_patcher.rb "AmneziaVPN.xcodeproj" "$SHORTVERSION" "$FULLVERSION" "$OSRUBY" "$NETWORKEXTENSION" || killProcess "Failed to merge xcode with wireguard"
|
||||
print G "done."
|
||||
|
||||
if command -v "sed" &>/dev/null; then
|
||||
|
@ -270,6 +249,6 @@ print G "done."
|
|||
sed -i '' '/<string>Original<\/string>/d' AmneziaVPN.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
|
||||
fi
|
||||
|
||||
print Y "Opening in XCode..."
|
||||
open AmneziaVPN.xcodeproj
|
||||
print G "All done!"
|
||||
print Y "Opening project in Xcode..."
|
||||
open AmneziaVPN.xcodeproj
|
||||
|
|
|
@ -9,7 +9,7 @@ class XCodeprojPatcher
|
|||
attr :target_main
|
||||
attr :target_extension
|
||||
|
||||
def run(file, shortVersion, fullVersion, platform, networkExtension, configHash, adjust_sdk_token)
|
||||
def run(file, shortVersion, fullVersion, platform, networkExtension, configHash)
|
||||
open_project file
|
||||
setup_project
|
||||
open_target_main
|
||||
|
@ -19,13 +19,7 @@ class XCodeprojPatcher
|
|||
group = @project.main_group.new_group('Configuration')
|
||||
@configFile = group.new_file('xcode.xconfig')
|
||||
|
||||
setup_target_main shortVersion, fullVersion, platform, networkExtension, configHash, adjust_sdk_token
|
||||
|
||||
# if platform == 'macos'
|
||||
# setup_target_loginitem shortVersion, fullVersion, configHash
|
||||
# setup_target_nativemessaging shortVersion, fullVersion, configHash
|
||||
# end
|
||||
|
||||
setup_target_main shortVersion, fullVersion, platform, networkExtension, configHash
|
||||
|
||||
if networkExtension
|
||||
setup_target_extension shortVersion, fullVersion, platform, configHash
|
||||
|
@ -59,7 +53,7 @@ class XCodeprojPatcher
|
|||
end
|
||||
|
||||
|
||||
def setup_target_main(shortVersion, fullVersion, platform, networkExtension, configHash, adjust_sdk_token)
|
||||
def setup_target_main(shortVersion, fullVersion, platform, networkExtension, configHash)
|
||||
@target_main.build_configurations.each do |config|
|
||||
config.base_configuration_reference = @configFile
|
||||
|
||||
|
@ -72,10 +66,8 @@ class XCodeprojPatcher
|
|||
"$(PROJECT_DIR)/3rd",
|
||||
"$(PROJECT_DIR)/3rd/OpenVPNAdapter/build/Release-iphoneos",
|
||||
"$(PROJECT_DIR)/3rd/ShadowSocks/build/Release-iphoneos",
|
||||
# "$(PROJECT_DIR)/3rd/PacketProcessor/build/Release-iphoneos",
|
||||
"$(PROJECT_DIR)/3rd/outline-go-tun2socks/build/ios",
|
||||
"${PROJECT_DIR}/3rd/CocoaAsyncSocket/build/Release-iphoneos",
|
||||
# "${PROJECT_DIR}/3rd/CocoaLumberjack/build/Release-iphoneos",
|
||||
]
|
||||
|
||||
# Versions and names
|
||||
|
@ -91,9 +83,6 @@ class XCodeprojPatcher
|
|||
config.build_settings['INFOPLIST_FILE'] ||= platform + '/app/Info.plist'
|
||||
if platform == 'ios'
|
||||
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'ios/app/main.entitlements'
|
||||
if adjust_sdk_token != ""
|
||||
config.build_settings['ADJUST_SDK_TOKEN'] = adjust_sdk_token
|
||||
end
|
||||
elsif networkExtension
|
||||
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'macos/app/app.entitlements'
|
||||
else
|
||||
|
@ -104,7 +93,7 @@ class XCodeprojPatcher
|
|||
config.build_settings['ENABLE_BITCODE'] ||= 'NO' if platform == 'ios'
|
||||
config.build_settings['SDKROOT'] = 'iphoneos' if platform == 'ios'
|
||||
config.build_settings['SWIFT_PRECOMPILE_BRIDGING_HEADER'] = 'NO' if platform == 'ios'
|
||||
config.build_settings['PATH'] = '${PATH}:/usr/local/go/bin:/usr/local/bin:/opt/homebrew/bin'
|
||||
config.build_settings['PATH'] = '${PATH}:/opt/local/bin:/usr/local/go/bin:/usr/local/bin:/opt/homebrew/bin'
|
||||
|
||||
groupId = "";
|
||||
if (platform == 'macos')
|
||||
|
@ -173,96 +162,23 @@ class XCodeprojPatcher
|
|||
}
|
||||
end
|
||||
|
||||
if (platform == 'ios' && adjust_sdk_token != "")
|
||||
if(platform == 'ios')
|
||||
|
||||
frameworks_group = @project.groups.find { |group| group.display_name == 'Frameworks' }
|
||||
frameworks_build_phase = @target_main.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }
|
||||
|
||||
framework_ref = frameworks_group.new_file('AdServices.framework')
|
||||
build_file = frameworks_build_phase.add_file_reference(framework_ref)
|
||||
build_file.settings = { 'ATTRIBUTES' => ['Weak'] }
|
||||
embed_frameworks_build_phase = project.new(Xcodeproj::Project::Object::PBXCopyFilesBuildPhase)
|
||||
embed_frameworks_build_phase.name = 'Embed Frameworks'
|
||||
embed_frameworks_build_phase.symbol_dst_subfolder_spec = :frameworks
|
||||
@target_main.build_phases << embed_frameworks_build_phase
|
||||
|
||||
framework_ref = frameworks_group.new_file('iAd.framework')
|
||||
frameworks_build_phase.add_file_reference(framework_ref)
|
||||
framework_ref = frameworks_group.new_file('3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNAdapter.framework')
|
||||
build_file = embed_frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
# Adjust SDK
|
||||
group = @project.main_group.new_group('AdjustSDK')
|
||||
|
||||
[
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityHandler.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityKind.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityPackage.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityState.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdjustFactory.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdRevenue.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAttribution.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAttributionHandler.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJBackoffStrategy.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSData+ADJAdditions.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSNumber+ADJAdditions.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSString+ADJAdditions.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJConfig.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJEvent.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJEventFailure.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJEventSuccess.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJLinkResolution.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJLogger.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJPackageBuilder.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJPackageHandler.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJPackageParams.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJRequestHandler.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJResponseData.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSdkClickHandler.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSessionFailure.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSessionParameters.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSessionSuccess.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSubscription.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJThirdPartySharing.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJTimerCycle.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJTimerOnce.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJUrlStrategy.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJUserDefaults.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/Adjust.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJUtil.h',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityHandler.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityKind.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityPackage.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJActivityState.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdjustFactory.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdRevenue.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAttribution.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAttributionHandler.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJBackoffStrategy.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSData+ADJAdditions.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSNumber+ADJAdditions.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSString+ADJAdditions.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJConfig.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJEvent.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJEventFailure.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJEventSuccess.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJLinkResolution.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJLogger.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJPackageBuilder.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJPackageHandler.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJPackageParams.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJRequestHandler.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJResponseData.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSdkClickHandler.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSessionFailure.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSessionParameters.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSessionSuccess.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJSubscription.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJThirdPartySharing.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJTimerCycle.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJTimerOnce.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJUrlStrategy.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJUserDefaults.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/Adjust.m',
|
||||
'3rd/adjust-ios-sdk/Adjust/ADJUtil.m',
|
||||
].each { |filename|
|
||||
file = group.new_file(filename)
|
||||
file_reference = @target_main.add_file_references([file], '-fobjc-arc')
|
||||
}
|
||||
frameworks_build_phase.add_file_reference(framework_ref)
|
||||
build_file.settings = { 'ATTRIBUTES' => ['CodeSignOnCopy', 'RemoveHeadersOnCopy'] }
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def setup_target_extension(shortVersion, fullVersion, platform, configHash)
|
||||
|
@ -288,12 +204,9 @@ class XCodeprojPatcher
|
|||
"$(PROJECT_DIR)/3rd/OpenVPNAdapter/build/Release-iphoneos",
|
||||
"$(PROJECT_DIR)/3rd/libleaf/lib",
|
||||
"$(PROJECT_DIR)/3rd/ShadowSocks/build/Release-iphoneos",
|
||||
# "$(PROJECT_DIR)/3rd/PacketProcessor/build/Release-iphoneos",
|
||||
"$(PROJECT_DIR)/3rd/outline-go-tun2socks/build/ios",
|
||||
"${PROJECT_DIR}/3rd/CocoaAsyncSocket/build/Release-iphoneos",
|
||||
# "${PROJECT_DIR}/3rd/CocoaLumberjack/build/Release-iphoneos",
|
||||
]
|
||||
# config.build_settings['LIBRARY_SEARCH_PATHS'] = [config.build_settings['LIBRARY_SEARCH_PATHS'], "$(PROJECT_DIR)/3rd/libleaf/lib"]
|
||||
|
||||
# Versions and names
|
||||
config.build_settings['MARKETING_VERSION'] ||= shortVersion
|
||||
|
@ -325,7 +238,7 @@ class XCodeprojPatcher
|
|||
"-framework",
|
||||
"OpenGLES",
|
||||
]
|
||||
config.build_settings['PATH'] = '${PATH}:/usr/local/go/bin'
|
||||
config.build_settings['PATH'] = '${PATH}:/opt/local/bin:/usr/local/go/bin'
|
||||
end
|
||||
|
||||
groupId = "";
|
||||
|
@ -379,17 +292,7 @@ class XCodeprojPatcher
|
|||
'platforms/ios/iostunnel.swift',
|
||||
'platforms/ios/ioslogger.swift',
|
||||
'platforms/ios/iosinterface.swift',
|
||||
# 'platforms/ios/ssprovider.swift',
|
||||
'platforms/ios/iosglue.mm',
|
||||
# 'platforms/ios/ssconnectivity.h',
|
||||
# 'platforms/ios/ssconnectivity.m',
|
||||
# 'platforms/ios/iosopenvpn2ssadapter.h',
|
||||
# 'platforms/ios/iosopenvpn2ssadapter.m',
|
||||
# 'platforms/ios/sspacket.h',
|
||||
# 'platforms/ios/sspacket.m',
|
||||
# 'platforms/ios/ssadapterpacketflow.h',
|
||||
# 'platforms/ios/tun2ssprovider.swift',
|
||||
# 'platforms/ios/tun2sockswriter.swift',
|
||||
].each { |filename|
|
||||
file = group.new_file(filename)
|
||||
@target_extension.add_file_references([file])
|
||||
|
@ -402,40 +305,10 @@ class XCodeprojPatcher
|
|||
|
||||
framework_ref = frameworks_group.new_file('libwg-go.a')
|
||||
frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
# framework_ref = frameworks_group.new_file('3rd/libleaf/lib/libleaf.a')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
framework_ref = frameworks_group.new_file('NetworkExtension.framework')
|
||||
frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
# framework_ref = frameworks_group.new_file('3rd/OpenVPNAdapter/build/Release-iphoneos/LZ4.framework')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
#
|
||||
# framework_ref = frameworks_group.new_file('3rd/OpenVPNAdapter/build/Release-iphoneos/mbedTLS.framework')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
#
|
||||
# framework_ref = frameworks_group.new_file('3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNClient.framework')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
framework_ref = frameworks_group.new_file('3rd/OpenVPNAdapter/build/Release-iphoneos/OpenVPNAdapter.framework')
|
||||
frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
# framework_ref = frameworks_group.new_file('3rd/ShadowSocks/build/Release-iphoneos/ShadowSocks.framework')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
#
|
||||
# framework_ref = frameworks_group.new_file('3rd/CocoaAsyncSocket/build/Release-iphoneos/CocoaAsyncSocket.framework')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
#
|
||||
# framework_ref = frameworks_group.new_file('3rd/outline-go-tun2socks/build/ios/Tun2socks.xcframework')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
# framework_ref = frameworks_group.new_file('3rd/CocoaLumberjack/build/Release-iphoneos/CocoaLumberjack.framework')
|
||||
# frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
|
||||
|
||||
|
||||
# This fails: @target_main.add_dependency @target_extension
|
||||
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||
container_proxy.container_portal = @project.root_object.uuid
|
||||
|
@ -492,6 +365,7 @@ class XCodeprojPatcher
|
|||
framework_ref = frameworks_group.new_file('balrog/balrog.a')
|
||||
frameworks_build_phase.add_file_reference(framework_ref)
|
||||
|
||||
|
||||
# This fails: @target_main.add_dependency target_balrog
|
||||
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||
container_proxy.container_portal = @project.root_object.uuid
|
||||
|
@ -599,7 +473,7 @@ class XCodeprojPatcher
|
|||
|
||||
# other configs
|
||||
config.build_settings['INFOPLIST_FILE'] ||= 'macos/loginitem/Info.plist'
|
||||
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'macos/loginitem/MozillaVPNLoginItem.entitlements'
|
||||
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'macos/loginitem/MozillaVPNLoginItem.entitlements' #TODO need to check this
|
||||
config.build_settings['CODE_SIGN_IDENTITY'] = 'Apple Development'
|
||||
config.build_settings['SKIP_INSTALL'] = 'YES'
|
||||
|
||||
|
@ -708,7 +582,7 @@ class XCodeprojPatcher
|
|||
copy_nativeMessagingManifest.dst_path = 'Contents/Resources/utils'
|
||||
|
||||
group = @project.main_group.new_group('WireGuardHelper')
|
||||
file = group.new_file 'extension/app/manifests/macos/mozillavpn.json'
|
||||
file = group.new_file 'extension/app/manifests/macos/mozillavpn.json' #TODO Need to check this
|
||||
|
||||
nativeMessagingManifest_file = copy_nativeMessagingManifest.add_file_reference file
|
||||
nativeMessagingManifest_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
|
||||
|
@ -744,8 +618,7 @@ configFile.each { |line|
|
|||
platform = "macos"
|
||||
platform = "ios" if ARGV[3] == "ios"
|
||||
networkExtension = true if ARGV[4] == "1"
|
||||
adjust_sdk_token = ARGV[5]
|
||||
|
||||
r = XCodeprojPatcher.new
|
||||
r.run ARGV[0], ARGV[1], ARGV[2], platform, networkExtension, config, adjust_sdk_token
|
||||
r.run ARGV[0], ARGV[1], ARGV[2], platform, networkExtension, config
|
||||
exit 0
|
||||
|
|
|
@ -83,8 +83,8 @@ void AppSettingsLogic::onPushButtonBackupAppConfigClicked()
|
|||
|
||||
void AppSettingsLogic::onPushButtonRestoreAppConfigClicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open backup"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.backup");
|
||||
QString fileName = QFileDialog::getOpenFileName(Q_NULLPTR, tr("Open backup"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.backup");
|
||||
|
||||
if (fileName.isEmpty()) return;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
|
|||
{
|
||||
m_settings->setDefaultServer(index);
|
||||
uiLogic()->onUpdateAllPages();
|
||||
emit currServerIdxChanged();
|
||||
}
|
||||
|
||||
void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
|
||||
|
@ -23,6 +24,11 @@ void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
|
|||
uiLogic()->goToPage(Page::ServerSettings);
|
||||
}
|
||||
|
||||
int ServerListLogic::currServerIdx() const
|
||||
{
|
||||
return m_settings->defaultServerIndex();
|
||||
}
|
||||
|
||||
void ServerListLogic::onUpdatePage()
|
||||
{
|
||||
const QJsonArray &servers = m_settings->serversArray();
|
||||
|
|
|
@ -10,8 +10,11 @@ class ServerListLogic : public PageLogicBase
|
|||
Q_OBJECT
|
||||
|
||||
READONLY_PROPERTY(QObject *, serverListModel)
|
||||
Q_PROPERTY(int currServerIdx READ currServerIdx NOTIFY currServerIdxChanged)
|
||||
|
||||
public:
|
||||
int currServerIdx() const;
|
||||
|
||||
Q_INVOKABLE void onUpdatePage() override;
|
||||
Q_INVOKABLE void onServerListPushbuttonDefaultClicked(int index);
|
||||
Q_INVOKABLE void onServerListPushbuttonSettingsClicked(int index);
|
||||
|
@ -20,5 +23,8 @@ public:
|
|||
explicit ServerListLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
~ServerListLogic() = default;
|
||||
|
||||
signals:
|
||||
void currServerIdxChanged();
|
||||
|
||||
};
|
||||
#endif // SERVER_LIST_LOGIC_H
|
||||
|
|
|
@ -135,9 +135,8 @@ void StartPageLogic::onPushButtonImport()
|
|||
|
||||
void StartPageLogic::onPushButtonImportOpenFile()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("Open profile"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.vpn");
|
||||
|
||||
QString fileName = QFileDialog::getOpenFileName(Q_NULLPTR, tr("Open profile"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), tr("*.vpn"));
|
||||
if (fileName.isEmpty()) return;
|
||||
|
||||
QFile file(fileName);
|
||||
|
@ -166,14 +165,6 @@ bool StartPageLogic::importConnection(const QJsonObject &profile)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!profile.contains(config_key::containers)) {
|
||||
uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
|
||||
uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
|
||||
uiLogic()->onUpdateAllPages();
|
||||
|
||||
emit uiLogic()->goToPage(Page::ServerContainers);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,17 @@ void ViewConfigLogic::importConfig()
|
|||
m_settings->addServer(configJson());
|
||||
m_settings->setDefaultServer(m_settings->serversCount() - 1);
|
||||
|
||||
emit uiLogic()->goToPage(Page::Vpn);
|
||||
emit uiLogic()->setStartPage(Page::Vpn);
|
||||
|
||||
if (!configJson().contains(config_key::containers) || configJson().value(config_key::containers).toArray().isEmpty()) {
|
||||
uiLogic()->selectedServerIndex = m_settings->defaultServerIndex();
|
||||
uiLogic()->selectedDockerContainer = m_settings->defaultContainer(uiLogic()->selectedServerIndex);
|
||||
uiLogic()->onUpdateAllPages();
|
||||
emit uiLogic()->goToPage(Page::Vpn);
|
||||
emit uiLogic()->setStartPage(Page::Vpn);
|
||||
emit uiLogic()->goToPage(Page::ServerContainers);
|
||||
} else {
|
||||
emit uiLogic()->goToPage(Page::Vpn);
|
||||
emit uiLogic()->setStartPage(Page::Vpn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ Drawer {
|
|||
signal containerSelected(int c_index)
|
||||
property int selectedIndex: -1
|
||||
|
||||
z: -3
|
||||
|
||||
y: 0
|
||||
x: 0
|
||||
edge: Qt.RightEdge
|
||||
|
@ -117,6 +115,7 @@ Drawer {
|
|||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
tb.currentIndex = index
|
||||
tb_other.currentIndex = -1
|
||||
|
@ -181,6 +180,7 @@ Drawer {
|
|||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
tb_other.currentIndex = index
|
||||
tb.currentIndex = -1
|
||||
|
|
|
@ -26,7 +26,7 @@ PageBase {
|
|||
}
|
||||
|
||||
Connections {
|
||||
target: Qt.platform.os != "ios" ? QrDecoderLogic : nil
|
||||
target: Qt.platform.os != "ios" ? QrDecoderLogic : null
|
||||
function onStartDecode() {
|
||||
console.debug("Starting QR decoder")
|
||||
loader.sourceComponent = component
|
||||
|
@ -71,7 +71,7 @@ PageBase {
|
|||
anchors.right: parent.right
|
||||
autoOrientation: true
|
||||
fillMode: VideoOutput.PreserveAspectFit
|
||||
filters: [ zxingFilter ]
|
||||
// filters: [ zxingFilter ]
|
||||
|
||||
|
||||
Rectangle {
|
||||
|
|
|
@ -40,11 +40,29 @@ PageBase {
|
|||
id: loader
|
||||
|
||||
anchors.top: caption.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottom: progressColumn.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
Column{
|
||||
height: 40
|
||||
id: progressColumn
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
ProgressBar {
|
||||
id: progress
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
value: QrDecoderLogic.totalChunksCount === 0? 0 : (QrDecoderLogic.receivedChunksCount/QrDecoderLogic.totalChunksCount)
|
||||
}
|
||||
Text {
|
||||
id: chunksCount
|
||||
text: "Progress: " + QrDecoderLogic.receivedChunksCount +"/"+QrDecoderLogic.totalChunksCount
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: component
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ PageBase {
|
|||
pageLoader.focus = true
|
||||
}
|
||||
|
||||
onContainerSelected: {
|
||||
onContainerSelected: function(c_index) {
|
||||
var containerProto = ContainerProps.defaultProtocol(c_index)
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,9 @@ PageBase {
|
|||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 20
|
||||
model: ServerListLogic.serverListModel
|
||||
highlightRangeMode: ListView.ApplyRange
|
||||
highlightMoveVelocity: -1
|
||||
currentIndex: ServerListLogic.currServerIdx
|
||||
spacing: 5
|
||||
clip: true
|
||||
delegate: Item {
|
||||
|
@ -55,10 +58,6 @@ PageBase {
|
|||
if (GC.isMobile()) {
|
||||
ServerListLogic.onServerListPushbuttonSettingsClicked(index)
|
||||
}
|
||||
else {
|
||||
listWidget_servers.currentIndex = index
|
||||
}
|
||||
|
||||
mouse.accepted = false
|
||||
}
|
||||
onEntered: {
|
||||
|
|
|
@ -27,7 +27,6 @@ PageProtocolBase {
|
|||
anchors.top: caption.bottom
|
||||
anchors.left: root.left
|
||||
anchors.right: root.right
|
||||
anchors.bottom: pb_save.top
|
||||
anchors.margins: 20
|
||||
anchors.topMargin: 10
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ New encryption keys pair will be generated.")
|
|||
Layout.bottomMargin: 10
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 40
|
||||
text: qsTr("Save to file")
|
||||
text: Qt.platform.os === "android" ? qsTr("Share") : qsTr("Save to file")
|
||||
enabled: tfShareCode.textArea.length > 0
|
||||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ PageShareProtocolBase {
|
|||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 40
|
||||
|
||||
text: qsTr("Save to file")
|
||||
text: Qt.platform.os === "android" ? qsTr("Share") : qsTr("Save to file")
|
||||
enabled: tfShareCode.textArea.length > 0
|
||||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ PageShareProtocolBase {
|
|||
Layout.preferredHeight: 40
|
||||
width: parent.width - 60
|
||||
|
||||
text: qsTr("Save to file")
|
||||
text: Qt.platform.os === "android" ? qsTr("Share") : qsTr("Save to file")
|
||||
enabled: tfShareCode.textArea.length > 0
|
||||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ PageShareProtocolBase {
|
|||
Layout.preferredHeight: 40
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Save to file")
|
||||
text: Qt.platform.os === "android" ? qsTr("Share") : qsTr("Save to file")
|
||||
enabled: tfShareCode.textArea.length > 0
|
||||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
|
|
|
@ -285,7 +285,6 @@ Window {
|
|||
Drawer {
|
||||
id: drawer_log
|
||||
|
||||
z: -3
|
||||
y: 0
|
||||
x: 0
|
||||
edge: Qt.BottomEdge
|
||||
|
|
|
@ -135,7 +135,7 @@ void UiLogic::initalizeUiLogic()
|
|||
pageLogic<VpnLogic>()->onConnectionStateChanged(VpnProtocol::Connected);
|
||||
}
|
||||
});
|
||||
if (!AndroidController::instance()->initialize()) {
|
||||
if (!AndroidController::instance()->initialize(pageLogic<StartPageLogic>())) {
|
||||
qCritical() << QString("Init failed") ;
|
||||
emit VpnProtocol::Error;
|
||||
return;
|
||||
|
@ -267,8 +267,6 @@ void UiLogic::onGotoCurrentProtocolsPage()
|
|||
emit goToPage(Page::ServerContainers);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//void UiLogic::showEvent(QShowEvent *event)
|
||||
//{
|
||||
//#if defined Q_OS_MACX
|
||||
|
@ -596,8 +594,9 @@ void UiLogic::saveTextFile(const QString& desc, const QString& suggestedName, QS
|
|||
if (fileName.isEmpty()) return;
|
||||
if (!fileName.toString().endsWith(ext)) fileName = QUrl(fileName.toString() + ext);
|
||||
#elif defined Q_OS_ANDROID
|
||||
fileName = QFileDialog::getSaveFileUrl(nullptr, suggestedName,
|
||||
QUrl::fromLocalFile(docDir), "*" + ext);
|
||||
qDebug() << "UiLogic::shareConfig" << data;
|
||||
AndroidController::instance()->shareConfig(data, suggestedName);
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (fileName.isEmpty()) return;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# current build 1
|
||||
!defined(BUILDVERSION, var):BUILDVERSION = 2
|
||||
# current build 6
|
||||
!defined(BUILDVERSION, var):BUILDVERSION = 7
|
|
@ -1,3 +1,4 @@
|
|||
#include "qtimer.h"
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
@ -34,7 +35,10 @@ VpnConnection::VpnConnection(std::shared_ptr<Settings> settings,
|
|||
std::shared_ptr<ServerController> serverController, QObject* parent) : QObject(parent),
|
||||
m_settings(settings),
|
||||
m_configurator(configurator),
|
||||
m_serverController(serverController)
|
||||
m_serverController(serverController),
|
||||
m_receivedBytes(0),
|
||||
m_sentBytes(0),
|
||||
m_isIOSConnected(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -48,11 +52,16 @@ VpnConnection::~VpnConnection()
|
|||
|
||||
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
||||
{
|
||||
emit bytesChanged(receivedBytes, sentBytes);
|
||||
emit bytesChanged(receivedBytes - m_receivedBytes, sentBytes - m_sentBytes);
|
||||
|
||||
m_receivedBytes = receivedBytes;
|
||||
m_sentBytes = sentBytes;
|
||||
|
||||
}
|
||||
|
||||
void VpnConnection::onConnectionStateChanged(VpnProtocol::VpnConnectionState state)
|
||||
{
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
if (IpcClient::Interface()) {
|
||||
if (state == VpnProtocol::Connected){
|
||||
|
@ -94,9 +103,33 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::VpnConnectionState sta
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
if (state == VpnProtocol::Connected){
|
||||
m_isIOSConnected = true;
|
||||
checkIOSStatus();
|
||||
}
|
||||
else {
|
||||
m_isIOSConnected = false;
|
||||
m_receivedBytes = 0;
|
||||
m_sentBytes = 0;
|
||||
}
|
||||
#endif
|
||||
emit connectionStateChanged(state);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
void VpnConnection::checkIOSStatus()
|
||||
{
|
||||
QTimer::singleShot(1000, [this]() {
|
||||
if(m_isIOSConnected){
|
||||
iosVpnProtocol->checkStatus();
|
||||
checkIOSStatus();
|
||||
}
|
||||
} );
|
||||
}
|
||||
#endif
|
||||
|
||||
const QString &VpnConnection::remoteAddress() const
|
||||
{
|
||||
return m_remoteAddress;
|
||||
|
@ -333,7 +366,10 @@ void VpnConnection::connectToVpn(int serverIndex,
|
|||
m_vpnProtocol.reset(androidVpnProtocol);
|
||||
#elif defined Q_OS_IOS
|
||||
Proto proto = ContainerProps::defaultProtocol(container);
|
||||
IOSVpnProtocol *iosVpnProtocol = new IOSVpnProtocol(proto, m_vpnConfiguration);
|
||||
//if (iosVpnProtocol==NULL) {
|
||||
iosVpnProtocol = new IOSVpnProtocol(proto, m_vpnConfiguration);
|
||||
//}
|
||||
// IOSVpnProtocol *iosVpnProtocol = new IOSVpnProtocol(proto, m_vpnConfiguration);
|
||||
if (!iosVpnProtocol->initialize()) {
|
||||
qDebug() << QString("Init failed") ;
|
||||
emit VpnProtocol::Error;
|
||||
|
@ -384,12 +420,19 @@ void VpnConnection::disconnectFromVpn()
|
|||
|
||||
VpnProtocol::VpnConnectionState VpnConnection::connectionState()
|
||||
{
|
||||
|
||||
|
||||
if (!m_vpnProtocol) return VpnProtocol::Disconnected;
|
||||
return m_vpnProtocol->connectionState();
|
||||
|
||||
}
|
||||
|
||||
bool VpnConnection::isConnected() const
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
|
||||
#endif
|
||||
|
||||
if (!m_vpnProtocol.data()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include "core/defs.h"
|
||||
#include "settings.h"
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include "protocols/ios_vpnprotocol.h"
|
||||
#endif
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
#include "core/ipcclient.h"
|
||||
#endif
|
||||
|
@ -74,6 +78,10 @@ protected slots:
|
|||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void onConnectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
void checkIOSStatus();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
QSharedPointer<VpnProtocol> m_vpnProtocol;
|
||||
|
||||
|
@ -85,10 +93,16 @@ private:
|
|||
QJsonObject m_vpnConfiguration;
|
||||
QJsonObject m_routeMode;
|
||||
QString m_remoteAddress;
|
||||
quint64 m_receivedBytes;
|
||||
quint64 m_sentBytes;
|
||||
bool m_isIOSConnected; //remove later move to isConnected,
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
IpcClient *m_IpcClient {nullptr};
|
||||
#endif
|
||||
#ifdef Q_OS_IOS
|
||||
IOSVpnProtocol * iosVpnProtocol{nullptr};
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // VPNCONNECTION_H
|
||||
|
|
|
@ -2,4 +2,4 @@ DEVELOPMENT_TEAM = X7UJ388FXK
|
|||
|
||||
GROUP_ID_IOS = group.org.amnezia.AmneziaVPN
|
||||
APP_ID_IOS = org.amnezia.AmneziaVPN
|
||||
NETEXT_ID_IOS = org.amnezia.AmneziaVPN.network-extension
|
||||
NETEXT_ID_IOS = org.amnezia.AmneziaVPN.network-extension
|
Loading…
Add table
Add a link
Reference in a new issue