mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-07-03 14:07:39 +02:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 81050542cf | |||
| 38c0c1ec5d | |||
| 32b985942a | |||
| 1cfe6a1e50 | |||
| 132b6bc083 | |||
| 2b5c2cb021 | |||
| 729d6ee6d3 | |||
| cd87253844 | |||
| 8cdaa0c2ee | |||
| d563d66b28 | |||
| 37327e30d3 | |||
| e0af63ce1c | |||
| 041d0fcab5 | |||
| 2a6960a4fb | |||
| 8481367fb6 | |||
| 70d6f9996d | |||
| 616d58e901 | |||
| 0bfbd82536 | |||
| 544ad4ba6e |
+32
-15
@@ -1,7 +1,36 @@
|
||||
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
set(AMNEZIAVPN_VERSION 4.8.14.6)
|
||||
set(AMNEZIAVPN_VERSION 4.8.13.1)
|
||||
|
||||
include(cmake/conan_bootstrap.cmake)
|
||||
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES ${CMAKE_SOURCE_DIR}/cmake/conan_provider.cmake)
|
||||
|
||||
if(APPLE)
|
||||
get_property(generator_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if (generator_is_multi_config)
|
||||
set(CONAN_INSTALL_BUILD_CONFIGURATIONS Release Debug MinSizeRel RelWithDebInfo)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "14.0" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "" FORCE)
|
||||
elseif(MACOS_NE)
|
||||
set(CONAN_INSTALL_ARGS "--build=missing;-o=&:macos_ne=True" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
else()
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "" FORCE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
set(CONAN_INSTALL_ARGS
|
||||
"--build=missing"
|
||||
"-o=*:page_16k=True"
|
||||
"-e=*:LDFLAGS=-Wl,-z,max-page-size=16384"
|
||||
CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION}
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
@@ -12,7 +41,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 2118)
|
||||
set(APP_ANDROID_VERSION_CODE 2107)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
@@ -32,16 +61,6 @@ set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(APPLE)
|
||||
if(IOS)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64")
|
||||
elseif(MACOS_NE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
|
||||
else()
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_subdirectory(client)
|
||||
|
||||
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
@@ -61,9 +80,7 @@ if(WIN32 AND NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
set(CPACK_PACKAGE_VENDOR "AmneziaVPN")
|
||||
set(CPACK_PACKAGE_VERSION ${AMNEZIAVPN_VERSION})
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "AmneziaVPN client")
|
||||
set(AMNEZIA_LICENSE_TXT "${CMAKE_BINARY_DIR}/LICENSE.txt")
|
||||
configure_file("${CMAKE_SOURCE_DIR}/LICENSE" "${AMNEZIA_LICENSE_TXT}" COPYONLY)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${AMNEZIA_LICENSE_TXT}")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "AmneziaVPN")
|
||||
set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
set(CPACK_PACKAGE_EXECUTABLES "AmneziaVPN" "AmneziaVPN")
|
||||
|
||||
+1
-1
Submodule client/3rd-prebuilt updated: 568b8d720d...b8c229288d
@@ -51,6 +51,13 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
|
||||
endif()
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
# 16KB page size support for Android 15+ / Google Play
|
||||
# Must be set before any targets are defined so it applies to all compiled-from-source libraries
|
||||
if(ANDROID)
|
||||
add_link_options("-Wl,-z,max-page-size=16384")
|
||||
endif()
|
||||
|
||||
qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
|
||||
@@ -78,7 +85,6 @@ set(AMNEZIAVPN_TS_FILES
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE AMNEZIAVPN_TS_SOURCES *.qrc *.cpp *.h *.ui)
|
||||
list(FILTER AMNEZIAVPN_TS_SOURCES EXCLUDE REGEX "qtgamepad/examples")
|
||||
|
||||
qt_create_translation(AMNEZIAVPN_QM_FILES ${AMNEZIAVPN_TS_SOURCES} ${AMNEZIAVPN_TS_FILES})
|
||||
|
||||
@@ -218,13 +224,6 @@ if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
${CMAKE_SOURCE_DIR}/client/3rd-prebuilt/deploy-prebuilt/${DEPLOY_PLATFORM_PATH}
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT} PRIVATE ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC} ${I18NQRC})
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[versions]
|
||||
agp = "8.5.2"
|
||||
agp = "8.6.1"
|
||||
kotlin = "1.9.24"
|
||||
androidx-core = "1.13.1"
|
||||
androidx-activity = "1.9.1"
|
||||
androidx-annotation = "1.8.2"
|
||||
androidx-biometric = "1.2.0-alpha05"
|
||||
androidx-camera = "1.3.4"
|
||||
androidx-camera = "1.5.3"
|
||||
androidx-fragment = "1.8.2"
|
||||
androidx-security-crypto = "1.1.0-alpha06"
|
||||
androidx-datastore = "1.1.1"
|
||||
|
||||
@@ -75,8 +75,6 @@ private const val OPEN_FILE_ACTION_CODE = 3
|
||||
private const val CHECK_NOTIFICATION_PERMISSION_ACTION_CODE = 4
|
||||
|
||||
private const val PREFS_NOTIFICATION_PERMISSION_ASKED = "NOTIFICATION_PERMISSION_ASKED"
|
||||
private const val OPEN_FILE_AFTER_RESUME_DELAY_MS = 400L
|
||||
private const val KEY_PENDING_OPEN_FILE_URI = "pending_open_file_uri"
|
||||
|
||||
class AmneziaActivity : QtActivity() {
|
||||
|
||||
@@ -92,12 +90,10 @@ class AmneziaActivity : QtActivity() {
|
||||
|
||||
private val actionResultHandlers = mutableMapOf<Int, ActivityResultHandler>()
|
||||
private val permissionRequestHandlers = mutableMapOf<Int, PermissionRequestHandler>()
|
||||
|
||||
|
||||
private var isActivityResumed = false
|
||||
private var hasWindowFocus = false
|
||||
private val resumeHandler = Handler(Looper.getMainLooper())
|
||||
private var pendingOpenFileUri: String? = null
|
||||
private var openFileDeliveryScheduled = false
|
||||
|
||||
private val vpnServiceEventHandler: Handler by lazy(NONE) {
|
||||
object : Handler(Looper.getMainLooper()) {
|
||||
@@ -200,24 +196,14 @@ class AmneziaActivity : QtActivity() {
|
||||
doBindService()
|
||||
}
|
||||
)
|
||||
pendingOpenFileUri = savedInstanceState?.getString(KEY_PENDING_OPEN_FILE_URI)
|
||||
openFileDeliveryScheduled = false
|
||||
registerBroadcastReceivers()
|
||||
intent?.let(::processIntent)
|
||||
runBlocking { vpnProto = proto.await() }
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
pendingOpenFileUri?.let { outState.putString(KEY_PENDING_OPEN_FILE_URI, it) }
|
||||
}
|
||||
|
||||
private fun loadLibs() {
|
||||
listOf(
|
||||
"rsapss",
|
||||
"crypto_3",
|
||||
"ssl_3",
|
||||
"ssh"
|
||||
"rsapss"
|
||||
).forEach {
|
||||
loadSharedLibrary(this.applicationContext, it)
|
||||
}
|
||||
@@ -281,7 +267,6 @@ class AmneziaActivity : QtActivity() {
|
||||
hasWindowFocus = false
|
||||
// Cancel all pending operations when activity stops
|
||||
resumeHandler.removeCallbacksAndMessages(null)
|
||||
openFileDeliveryScheduled = false
|
||||
Log.d(TAG, "Stop Amnezia activity")
|
||||
doUnbindService()
|
||||
mainScope.launch {
|
||||
@@ -295,7 +280,7 @@ class AmneziaActivity : QtActivity() {
|
||||
super.onWindowFocusChanged(hasFocus)
|
||||
hasWindowFocus = hasFocus
|
||||
Log.d(TAG, "Window focus changed: hasFocus=$hasFocus")
|
||||
|
||||
|
||||
// Cancel pending operations if window loses focus
|
||||
if (!hasFocus) {
|
||||
resumeHandler.removeCallbacksAndMessages(null)
|
||||
@@ -303,31 +288,35 @@ class AmneziaActivity : QtActivity() {
|
||||
}
|
||||
|
||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||
val deviceId = event.deviceId
|
||||
val keyCode = event.keyCode
|
||||
val pressed = event.action == KeyEvent.ACTION_DOWN
|
||||
val source = event.source
|
||||
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_BUTTON_A,
|
||||
KeyEvent.KEYCODE_BUTTON_B,
|
||||
KeyEvent.KEYCODE_BUTTON_X,
|
||||
KeyEvent.KEYCODE_BUTTON_Y,
|
||||
KeyEvent.KEYCODE_BUTTON_START,
|
||||
KeyEvent.KEYCODE_BUTTON_SELECT -> {
|
||||
nativeGamepadKeyEvent(0, keyCode, pressed)
|
||||
if (deviceId < 0 && pressed) {
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_BUTTON_A,
|
||||
KeyEvent.KEYCODE_BUTTON_B,
|
||||
KeyEvent.KEYCODE_BUTTON_X,
|
||||
KeyEvent.KEYCODE_BUTTON_Y,
|
||||
KeyEvent.KEYCODE_BUTTON_START,
|
||||
KeyEvent.KEYCODE_BUTTON_SELECT,
|
||||
KeyEvent.KEYCODE_DPAD_CENTER -> {
|
||||
nativeGamepadKeyEvent(0, keyCode, true)
|
||||
nativeGamepadKeyEvent(0, keyCode, false)
|
||||
return true
|
||||
}
|
||||
}
|
||||
KeyEvent.KEYCODE_DPAD_CENTER,
|
||||
KeyEvent.KEYCODE_DPAD_UP,
|
||||
KeyEvent.KEYCODE_DPAD_DOWN,
|
||||
KeyEvent.KEYCODE_DPAD_LEFT,
|
||||
KeyEvent.KEYCODE_DPAD_RIGHT -> {
|
||||
val syntheticKeyCode = if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) KeyEvent.KEYCODE_ENTER else keyCode
|
||||
val synthetic = KeyEvent(
|
||||
event.downTime, event.eventTime, event.action, syntheticKeyCode,
|
||||
event.repeatCount, event.metaState, -1, event.scanCode,
|
||||
event.flags, InputDevice.SOURCE_KEYBOARD
|
||||
)
|
||||
return super.dispatchKeyEvent(synthetic)
|
||||
}
|
||||
|
||||
// Real gamepad events (deviceId >= 0)
|
||||
if (deviceId >= 0) {
|
||||
val isGamepad = (source and InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD
|
||||
val isJoystick = (source and InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK
|
||||
val isDpad = (source and InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
|
||||
if (isGamepad || isJoystick || isDpad) {
|
||||
nativeGamepadKeyEvent(deviceId, keyCode, pressed)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +330,6 @@ class AmneziaActivity : QtActivity() {
|
||||
isActivityResumed = false
|
||||
// Cancel all pending operations when activity pauses
|
||||
resumeHandler.removeCallbacksAndMessages(null)
|
||||
openFileDeliveryScheduled = false
|
||||
Log.d(TAG, "Pause Amnezia activity")
|
||||
}
|
||||
|
||||
@@ -350,21 +338,6 @@ class AmneziaActivity : QtActivity() {
|
||||
isActivityResumed = true
|
||||
Log.d(TAG, "Resume Amnezia activity")
|
||||
|
||||
if (pendingOpenFileUri != null && !openFileDeliveryScheduled) {
|
||||
val uri = pendingOpenFileUri!!
|
||||
openFileDeliveryScheduled = true
|
||||
resumeHandler.postDelayed({
|
||||
if (!isFinishing && !isDestroyed) {
|
||||
pendingOpenFileUri = null
|
||||
openFileDeliveryScheduled = false
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
QtAndroidController.onFileOpened(uri)
|
||||
}
|
||||
}
|
||||
}, OPEN_FILE_AFTER_RESUME_DELAY_MS)
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
window.decorView.apply {
|
||||
invalidate()
|
||||
@@ -375,13 +348,13 @@ class AmneziaActivity : QtActivity() {
|
||||
sendTouch(1f, 1f)
|
||||
}
|
||||
}, 100)
|
||||
|
||||
|
||||
resumeHandler.postDelayed({
|
||||
if (isActivityResumed && hasWindowFocus && !isFinishing && !isDestroyed) {
|
||||
sendTouch(2f, 2f)
|
||||
}
|
||||
}, 200)
|
||||
|
||||
|
||||
resumeHandler.postDelayed({
|
||||
if (isActivityResumed && hasWindowFocus && !isFinishing && !isDestroyed) {
|
||||
requestLayout()
|
||||
@@ -427,25 +400,25 @@ class AmneziaActivity : QtActivity() {
|
||||
ViewCompat.setOnApplyWindowInsetsListener(window.decorView) { view, windowInsets ->
|
||||
val imeInsets = windowInsets.getInsets(WindowInsetsCompat.Type.ime())
|
||||
val imeVisible = windowInsets.isVisible(WindowInsetsCompat.Type.ime())
|
||||
|
||||
|
||||
val imeHeight = if (imeVisible) imeInsets.bottom else 0
|
||||
|
||||
val density = resources.displayMetrics.density
|
||||
val imeHeightDp = (imeHeight / density).toInt()
|
||||
|
||||
|
||||
// Also track system bars (navigation bar, status bar) changes
|
||||
val systemBarsInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val navBarHeight = systemBarsInsets.bottom
|
||||
val navBarHeightDp = (navBarHeight / density).toInt()
|
||||
val statusBarHeight = systemBarsInsets.top
|
||||
val statusBarHeightDp = (statusBarHeight / density).toInt()
|
||||
|
||||
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
QtAndroidController.onImeInsetsChanged(imeHeightDp)
|
||||
QtAndroidController.onSystemBarsInsetsChanged(navBarHeightDp, statusBarHeightDp)
|
||||
}
|
||||
|
||||
|
||||
// Return windowInsets instead of CONSUMED to allow proper handling
|
||||
windowInsets
|
||||
}
|
||||
@@ -781,13 +754,9 @@ class AmneziaActivity : QtActivity() {
|
||||
grantUriPermission(packageName, this, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}?.toString() ?: ""
|
||||
Log.v(TAG, "Open file: $uri")
|
||||
if (uri.isNotEmpty()) {
|
||||
pendingOpenFileUri = uri
|
||||
} else {
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
QtAndroidController.onFileOpened(uri)
|
||||
}
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
QtAndroidController.onFileOpened(uri)
|
||||
}
|
||||
}
|
||||
))
|
||||
|
||||
@@ -33,10 +33,7 @@ class TvFilePicker : ComponentActivity() {
|
||||
return intent
|
||||
}
|
||||
}) {
|
||||
setResult(RESULT_OK, Intent().apply {
|
||||
data = it
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
})
|
||||
setResult(RESULT_OK, Intent().apply { data = it })
|
||||
finish()
|
||||
}
|
||||
|
||||
|
||||
+13
-75
@@ -8,76 +8,6 @@ include(${CLIENT_ROOT_DIR}/cmake/QSimpleCrypto.cmake)
|
||||
|
||||
include(${CLIENT_ROOT_DIR}/3rd/qrcodegen/qrcodegen.cmake)
|
||||
|
||||
set(LIBSSH_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/")
|
||||
set(OPENSSL_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/")
|
||||
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
|
||||
|
||||
if(WIN32)
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include")
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86_64/ssh.lib")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86_64")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib")
|
||||
else()
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86/ssh.lib")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
if(MACOS_NE)
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libz.a")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/macos/universal2")
|
||||
else()
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/x86_64/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/x86_64/libz.a")
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/macos/x86_64")
|
||||
endif()
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/macos/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/macos/lib/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/macos/lib/libcrypto.a")
|
||||
elseif(IOS)
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/ios/arm64")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/ios/arm64/libssh.a")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/ios/arm64/libz.a")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/ios/iphone/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/ios/iphone/lib/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/ios/iphone/lib/libcrypto.a")
|
||||
elseif(ANDROID)
|
||||
set(abi ${CMAKE_ANDROID_ARCH_ABI})
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/android/${abi}")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/android/${abi}/libssh.so")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/android/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/android/${abi}/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/android/${abi}/libcrypto.a")
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/android/${abi}")
|
||||
elseif(LINUX)
|
||||
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/linux/x86_64")
|
||||
set(ZLIB_LIB_PATH "${LIBSSH_ROOT_DIR}/linux/x86_64/libz.a")
|
||||
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/linux/x86_64/libssh.a")
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/linux/include")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/linux/x86_64/libssl.a")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/linux/x86_64/libcrypto.a")
|
||||
endif()
|
||||
|
||||
file(COPY ${OPENSSL_LIB_SSL_PATH} ${OPENSSL_LIB_CRYPTO_PATH}
|
||||
DESTINATION ${OPENSSL_LIBRARIES_DIR})
|
||||
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${LIBSSH_LIB_PATH}
|
||||
${ZLIB_LIB_PATH}
|
||||
)
|
||||
|
||||
set(LIBS ${LIBS}
|
||||
${OPENSSL_LIB_SSL_PATH}
|
||||
${OPENSSL_LIB_CRYPTO_PATH}
|
||||
)
|
||||
|
||||
add_compile_definitions(_WINSOCKAPI_)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
@@ -106,12 +36,20 @@ endif()
|
||||
set(LIBS ${LIBS} qt6keychain)
|
||||
|
||||
include_directories(
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${LIBSSH_INCLUDE_DIR}/include
|
||||
${LIBSSH_ROOT_DIR}/include
|
||||
${CLIENT_ROOT_DIR}/3rd/libssh/include
|
||||
${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/src/include
|
||||
${CLIENT_ROOT_DIR}/3rd/qtkeychain/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/libssh/include
|
||||
)
|
||||
|
||||
if(ANDROID)
|
||||
find_package(android-openssl REQUIRED)
|
||||
# CMakeConfigDeps doesn't propagate include dirs onto IMPORTED targets;
|
||||
# use the legacy variable that IS correctly populated by the config file.
|
||||
include_directories(${android-openssl_INCLUDE_DIRS})
|
||||
else()
|
||||
find_package(openssl REQUIRED)
|
||||
endif()
|
||||
list(APPEND LIBS OpenSSL::SSL OpenSSL::Crypto)
|
||||
|
||||
find_package(libssh REQUIRED)
|
||||
list(APPEND LIBS ssh::ssh)
|
||||
|
||||
+10
-14
@@ -42,18 +42,14 @@ set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/core/installedAppsImageProvider.cpp
|
||||
)
|
||||
|
||||
foreach(abi IN ITEMS ${QT_ANDROID_ABIS})
|
||||
set_property(TARGET ${PROJECT} PROPERTY QT_ANDROID_EXTRA_LIBS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/amneziawg/android/${abi}/libwg-go.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libck-ovpn-plugin.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpn3.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/libovpnutil.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/android/${abi}/librsapss.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/android/${abi}/libcrypto_3.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/android/${abi}/libssl_3.so
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/android/${abi}/libssh.so
|
||||
)
|
||||
endforeach()
|
||||
|
||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/xray/android/libxray.aar
|
||||
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/android/xray/libXray)
|
||||
find_package(awg-android REQUIRED)
|
||||
set(LIBS ${LIBS} amnezia::awg-android)
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${AMNEZIA_ANDROID_LIBWG_PATH} ${AMNEZIA_ANDROID_LIBWG_QUICK_PATH})
|
||||
|
||||
find_package(amnezia-libxray REQUIRED)
|
||||
file(COPY ${AMNEZIA_LIBXRAY_PATH} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/android/xray/libXray)
|
||||
|
||||
find_package(openvpn-pt-android REQUIRED)
|
||||
set(LIBS ${LIBS} amnezia::openvpn-pt-android)
|
||||
set_property(TARGET ${PROJECT} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${OPENVPN_PT_ANDROID_LIBCK_OVPN_PLUGIN_PATH})
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
message("Client iOS build")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0)
|
||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
|
||||
|
||||
enable_language(OBJC)
|
||||
enable_language(OBJCXX)
|
||||
enable_language(Swift)
|
||||
@@ -137,11 +135,3 @@ set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
|
||||
|
||||
add_subdirectory(ios/networkextension)
|
||||
add_dependencies(${PROJECT} networkextension)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/)
|
||||
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework")
|
||||
|
||||
|
||||
@@ -23,9 +23,6 @@ set_target_properties(${PROJECT} PROPERTIES
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
|
||||
)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE INTERNAL "" FORCE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ui/macos_util.h
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
message("Client ==> MacOS NE build")
|
||||
|
||||
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
|
||||
|
||||
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
|
||||
@@ -152,19 +151,6 @@ message(${QtCore_location})
|
||||
|
||||
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
|
||||
|
||||
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos/OpenVPNAdapter.framework"
|
||||
)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos)
|
||||
target_link_libraries("AmneziaVPNNetworkExtension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos/OpenVPNAdapter.framework")
|
||||
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks
|
||||
COMMAND /usr/bin/find "$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks/OpenVPNAdapter.framework" -name "*.sha256" -delete
|
||||
COMMAND /usr/bin/codesign --force --sign "Apple Distribution: Privacy Technologies OU"
|
||||
"$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks/OpenVPNAdapter.framework/Versions/Current/OpenVPNAdapter"
|
||||
COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Signing OpenVPNAdapter framework"
|
||||
)
|
||||
|
||||
@@ -135,7 +135,7 @@ void CoreController::initControllers()
|
||||
new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_sitesModel, m_appSplitTunnelingModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||
|
||||
m_sitesController.reset(new SitesController(m_settings, m_sitesModel));
|
||||
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
||||
m_engine->rootContext()->setContextProperty("SitesController", m_sitesController.get());
|
||||
|
||||
m_allowedDnsController.reset(new AllowedDnsController(m_settings, m_allowedDnsModel));
|
||||
@@ -368,11 +368,7 @@ void CoreController::initPrepareConfigHandler()
|
||||
return;
|
||||
}
|
||||
|
||||
m_installController->validateConfig();
|
||||
});
|
||||
|
||||
connect(m_installController.get(), &InstallController::configValidated, this, [this](bool isValid) {
|
||||
if (!isValid) {
|
||||
if (!m_installController->isConfigValid()) {
|
||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -337,9 +337,6 @@ QStringList GatewayController::getProxyUrls(const QString &serviceType, const QS
|
||||
} else {
|
||||
baseUrls = QString(PROD_S3_ENDPOINT).split(", ");
|
||||
}
|
||||
std::random_device randomDevice;
|
||||
std::mt19937 generator(randomDevice());
|
||||
std::shuffle(baseUrls.begin(), baseUrls.end(), generator);
|
||||
|
||||
QByteArray key = m_isDevEnvironment ? DEV_AGW_PUBLIC_KEY : PROD_AGW_PUBLIC_KEY;
|
||||
|
||||
|
||||
@@ -110,21 +110,14 @@ set_property(TARGET networkextension APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
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)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
target_sources(networkextension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/ios/arm64/libwg-go.a)
|
||||
find_package(openvpnadapter REQUIRED)
|
||||
target_link_libraries(networkextension PRIVATE amnezia::openvpnadapter)
|
||||
|
||||
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework)
|
||||
find_package(awg-apple REQUIRED)
|
||||
target_link_libraries(networkextension PRIVATE amnezia::awg-apple)
|
||||
|
||||
find_package(hev-socks5-tunnel REQUIRED)
|
||||
target_link_libraries(networkextension PRIVATE heiher::hev-socks5-tunnel)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#ifndef WIREGUARD_GO_VERSION
|
||||
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
|
||||
#endif // WIREGUARD_GO_VERSION
|
||||
@@ -114,25 +114,14 @@ set_property(TARGET AmneziaVPNNetworkExtension APPEND PROPERTY RESOURCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
|
||||
)
|
||||
|
||||
## Build wireguard-go-version.h
|
||||
execute_process(
|
||||
COMMAND go list -m golang.zx2c4.com/wireguard
|
||||
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)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
target_sources(AmneziaVPNNetworkExtension PRIVATE
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
|
||||
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR})
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/macos/universal2/libwg-go.a)
|
||||
find_package(openvpnadapter REQUIRED)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::openvpnadapter)
|
||||
|
||||
message(${CLIENT_ROOT_DIR})
|
||||
message(${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
|
||||
find_package(awg-apple REQUIRED)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::awg-apple)
|
||||
|
||||
target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers)
|
||||
find_package(hev-socks5-tunnel REQUIRED)
|
||||
target_link_libraries(AmneziaVPNNetworkExtension PRIVATE heiher::hev-socks5-tunnel)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#ifndef WIREGUARD_GO_VERSION
|
||||
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
|
||||
#endif // WIREGUARD_GO_VERSION
|
||||
@@ -75,7 +75,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
qInfo().noquote() << QString("Started %1 version %2 %3").arg(APPLICATION_NAME, APP_VERSION, GIT_COMMIT_HASH);
|
||||
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
|
||||
qInfo().noquote() << QString("SSL backend: %1").arg(QSslSocket::sslLibraryVersionString());
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||
|
||||
QDir appPath(QCoreApplication::applicationDirPath());
|
||||
QStringList wgArgs = {"-f", "amn0"};
|
||||
m_tunnel.start(appPath.filePath("../../client/bin/wireguard-go"), wgArgs);
|
||||
m_tunnel.start(appPath.filePath("../../client/bin/amneziawg-go"), wgArgs);
|
||||
if (!m_tunnel.waitForStarted(WG_TUN_PROC_TIMEOUT)) {
|
||||
logger.error() << "Unable to start tunnel process due to timeout";
|
||||
m_tunnel.kill();
|
||||
|
||||
@@ -79,7 +79,7 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||
|
||||
QDir appPath(QCoreApplication::applicationDirPath());
|
||||
QStringList wgArgs = {"-f", "utun"};
|
||||
m_tunnel.start(appPath.filePath("wireguard-go"), wgArgs);
|
||||
m_tunnel.start(appPath.filePath("amneziawg-go"), wgArgs);
|
||||
if (!m_tunnel.waitForStarted(WG_TUN_PROC_TIMEOUT)) {
|
||||
logger.error() << "Unable to start tunnel process due to timeout";
|
||||
m_tunnel.kill();
|
||||
|
||||
@@ -124,14 +124,14 @@ ErrorCode XrayProtocol::startTun2Socks()
|
||||
m_tun2socksProcess->setProgram(PermittedProcess::Tun2Socks);
|
||||
m_tun2socksProcess->setArguments({"-device", QString("tun://%1").arg(tunName), "-proxy", "socks5://127.0.0.1:10808" });
|
||||
|
||||
connect(m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this, [this]() {
|
||||
auto readAllStandardOutput = m_tun2socksProcess->readAllStandardOutput();
|
||||
if (!readAllStandardOutput.waitForFinished()) {
|
||||
connect(m_tun2socksProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardError, this, [this]() {
|
||||
auto readAllStandardError = m_tun2socksProcess->readAllStandardError();
|
||||
if (!readAllStandardError.waitForFinished()) {
|
||||
qWarning() << "Failed to read output from tun2socks";
|
||||
return;
|
||||
}
|
||||
|
||||
const QString line = readAllStandardOutput.returnValue();
|
||||
const QString line = readAllStandardError.returnValue();
|
||||
|
||||
if (!line.contains("[TCP]") && !line.contains("[UDP]"))
|
||||
qDebug() << "[tun2socks]:" << line;
|
||||
|
||||
+21
-14
@@ -35,12 +35,13 @@ SecureQSettings::SecureQSettings(const QString &organization, const QString &app
|
||||
}
|
||||
}
|
||||
m_settings.setValue("Conf/encrypted", true);
|
||||
m_settings.sync();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant SecureQSettings::value(const QString &key, const QVariant &defaultValue) const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
if (m_cache.contains(key)) {
|
||||
return m_cache.value(key);
|
||||
@@ -84,7 +85,7 @@ QVariant SecureQSettings::value(const QString &key, const QVariant &defaultValue
|
||||
|
||||
void SecureQSettings::setValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
if (encryptionRequired() && encryptedKeys.contains(key)) {
|
||||
if (!getEncKey().isEmpty() && !getEncIv().isEmpty()) {
|
||||
@@ -106,20 +107,26 @@ void SecureQSettings::setValue(const QString &key, const QVariant &value)
|
||||
}
|
||||
|
||||
m_cache.insert(key, value);
|
||||
sync();
|
||||
}
|
||||
|
||||
void SecureQSettings::remove(const QString &key)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QMutexLocker locker(&mutex);
|
||||
|
||||
m_settings.remove(key);
|
||||
m_cache.remove(key);
|
||||
|
||||
sync();
|
||||
}
|
||||
|
||||
void SecureQSettings::sync()
|
||||
{
|
||||
m_settings.sync();
|
||||
}
|
||||
|
||||
QByteArray SecureQSettings::backupAppConfig() const
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
QJsonObject cfg;
|
||||
|
||||
const auto needToBackup = [this](const auto &key) {
|
||||
@@ -154,8 +161,6 @@ QByteArray SecureQSettings::backupAppConfig() const
|
||||
|
||||
bool SecureQSettings::restoreAppConfig(const QByteArray &json)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
QJsonObject cfg = QJsonDocument::fromJson(json).object();
|
||||
if (cfg.isEmpty())
|
||||
return false;
|
||||
@@ -168,16 +173,10 @@ bool SecureQSettings::restoreAppConfig(const QByteArray &json)
|
||||
setValue(key, cfg.value(key).toVariant());
|
||||
}
|
||||
|
||||
sync();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SecureQSettings::clearSettings()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_settings.clear();
|
||||
m_cache.clear();
|
||||
}
|
||||
|
||||
QByteArray SecureQSettings::encryptText(const QByteArray &value) const
|
||||
{
|
||||
QSimpleCrypto::QBlockCipher cipher;
|
||||
@@ -295,3 +294,11 @@ void SecureQSettings::setSecTag(const QString &tag, const QByteArray &data)
|
||||
qCritical() << "SecureQSettings::setSecTag Error:" << job->errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void SecureQSettings::clearSettings()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
m_settings.clear();
|
||||
m_cache.clear();
|
||||
sync();
|
||||
}
|
||||
|
||||
@@ -16,16 +16,14 @@ public:
|
||||
explicit SecureQSettings(const QString &organization, const QString &application = QString(),
|
||||
QObject *parent = nullptr);
|
||||
|
||||
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||
void setValue(const QString &key, const QVariant &value);
|
||||
Q_INVOKABLE QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||
Q_INVOKABLE void setValue(const QString &key, const QVariant &value);
|
||||
void remove(const QString &key);
|
||||
void sync();
|
||||
|
||||
QByteArray backupAppConfig() const;
|
||||
bool restoreAppConfig(const QByteArray &json);
|
||||
|
||||
void clearSettings();
|
||||
|
||||
private:
|
||||
QByteArray encryptText(const QByteArray &value) const;
|
||||
QByteArray decryptText(const QByteArray &ba) const;
|
||||
|
||||
@@ -37,6 +35,9 @@ private:
|
||||
static QByteArray getSecTag(const QString &tag);
|
||||
static void setSecTag(const QString &tag, const QByteArray &data);
|
||||
|
||||
void clearSettings();
|
||||
|
||||
private:
|
||||
QSettings m_settings;
|
||||
|
||||
mutable QHash<QString, QVariant> m_cache;
|
||||
@@ -52,7 +53,7 @@ private:
|
||||
|
||||
const QByteArray magicString { "EncData" }; // Magic keyword used for mark encrypted QByteArray
|
||||
|
||||
mutable QRecursiveMutex m_mutex;
|
||||
mutable QMutex mutex;
|
||||
};
|
||||
|
||||
#endif // SECUREQSETTINGS_H
|
||||
|
||||
+57
-34
@@ -21,10 +21,10 @@ Settings::Settings(QObject *parent) : QObject(parent), m_settings(ORGANIZATION_N
|
||||
{
|
||||
// Import old settings
|
||||
if (serversCount() == 0) {
|
||||
QString user = m_settings.value("Server/userName").toString();
|
||||
QString password = m_settings.value("Server/password").toString();
|
||||
QString serverName = m_settings.value("Server/serverName").toString();
|
||||
int port = m_settings.value("Server/serverPort").toInt();
|
||||
QString user = value("Server/userName").toString();
|
||||
QString password = value("Server/password").toString();
|
||||
QString serverName = value("Server/serverName").toString();
|
||||
int port = value("Server/serverPort").toInt();
|
||||
|
||||
if (!user.isEmpty() && !password.isEmpty() && !serverName.isEmpty()) {
|
||||
QJsonObject server;
|
||||
@@ -222,7 +222,7 @@ QString Settings::nextAvailableServerName() const
|
||||
|
||||
void Settings::setSaveLogs(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/saveLogs", enabled);
|
||||
setValue("Conf/saveLogs", enabled);
|
||||
#ifndef Q_OS_ANDROID
|
||||
if (!isSaveLogs()) {
|
||||
Logger::deInit();
|
||||
@@ -242,12 +242,12 @@ void Settings::setSaveLogs(bool enabled)
|
||||
|
||||
QDateTime Settings::getLogEnableDate()
|
||||
{
|
||||
return m_settings.value("Conf/logEnableDate").toDateTime();
|
||||
return value("Conf/logEnableDate").toDateTime();
|
||||
}
|
||||
|
||||
void Settings::setLogEnableDate(QDateTime date)
|
||||
{
|
||||
m_settings.setValue("Conf/logEnableDate", date);
|
||||
setValue("Conf/logEnableDate", date);
|
||||
}
|
||||
|
||||
QString Settings::routeModeString(RouteMode mode) const
|
||||
@@ -261,17 +261,17 @@ QString Settings::routeModeString(RouteMode mode) const
|
||||
|
||||
Settings::RouteMode Settings::routeMode() const
|
||||
{
|
||||
return static_cast<RouteMode>(m_settings.value("Conf/routeMode", 0).toInt());
|
||||
return static_cast<RouteMode>(value("Conf/routeMode", 0).toInt());
|
||||
}
|
||||
|
||||
bool Settings::isSitesSplitTunnelingEnabled() const
|
||||
{
|
||||
return m_settings.value("Conf/sitesSplitTunnelingEnabled", false).toBool();
|
||||
return value("Conf/sitesSplitTunnelingEnabled", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setSitesSplitTunnelingEnabled(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/sitesSplitTunnelingEnabled", enabled);
|
||||
setValue("Conf/sitesSplitTunnelingEnabled", enabled);
|
||||
}
|
||||
|
||||
bool Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
|
||||
@@ -359,12 +359,12 @@ void Settings::removeAllVpnSites(RouteMode mode)
|
||||
|
||||
QString Settings::primaryDns() const
|
||||
{
|
||||
return m_settings.value("Conf/primaryDns", cloudFlareNs1).toString();
|
||||
return value("Conf/primaryDns", cloudFlareNs1).toString();
|
||||
}
|
||||
|
||||
QString Settings::secondaryDns() const
|
||||
{
|
||||
return m_settings.value("Conf/secondaryDns", cloudFlareNs2).toString();
|
||||
return value("Conf/secondaryDns", cloudFlareNs2).toString();
|
||||
}
|
||||
|
||||
void Settings::clearSettings()
|
||||
@@ -386,18 +386,18 @@ QString Settings::appsRouteModeString(AppsRouteMode mode) const
|
||||
|
||||
Settings::AppsRouteMode Settings::getAppsRouteMode() const
|
||||
{
|
||||
return static_cast<AppsRouteMode>(m_settings.value("Conf/appsRouteMode", 0).toInt());
|
||||
return static_cast<AppsRouteMode>(value("Conf/appsRouteMode", 0).toInt());
|
||||
}
|
||||
|
||||
void Settings::setAppsRouteMode(AppsRouteMode mode)
|
||||
{
|
||||
m_settings.setValue("Conf/appsRouteMode", mode);
|
||||
setValue("Conf/appsRouteMode", mode);
|
||||
}
|
||||
|
||||
QVector<InstalledAppInfo> Settings::getVpnApps(AppsRouteMode mode) const
|
||||
{
|
||||
QVector<InstalledAppInfo> apps;
|
||||
auto appsArray = m_settings.value("Conf/" + appsRouteModeString(mode)).toJsonArray();
|
||||
auto appsArray = value("Conf/" + appsRouteModeString(mode)).toJsonArray();
|
||||
for (const auto &app : appsArray) {
|
||||
InstalledAppInfo appInfo;
|
||||
appInfo.appName = app.toObject().value("appName").toString();
|
||||
@@ -419,42 +419,43 @@ void Settings::setVpnApps(AppsRouteMode mode, const QVector<InstalledAppInfo> &a
|
||||
appInfo.insert("appPath", app.appPath);
|
||||
appsArray.push_back(appInfo);
|
||||
}
|
||||
m_settings.setValue("Conf/" + appsRouteModeString(mode), appsArray);
|
||||
setValue("Conf/" + appsRouteModeString(mode), appsArray);
|
||||
m_settings.sync();
|
||||
}
|
||||
|
||||
bool Settings::isAppsSplitTunnelingEnabled() const
|
||||
{
|
||||
return m_settings.value("Conf/appsSplitTunnelingEnabled", false).toBool();
|
||||
return value("Conf/appsSplitTunnelingEnabled", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setAppsSplitTunnelingEnabled(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/appsSplitTunnelingEnabled", enabled);
|
||||
setValue("Conf/appsSplitTunnelingEnabled", enabled);
|
||||
}
|
||||
|
||||
bool Settings::isKillSwitchEnabled() const
|
||||
{
|
||||
return m_settings.value("Conf/killSwitchEnabled", true).toBool();
|
||||
return value("Conf/killSwitchEnabled", true).toBool();
|
||||
}
|
||||
|
||||
void Settings::setKillSwitchEnabled(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/killSwitchEnabled", enabled);
|
||||
setValue("Conf/killSwitchEnabled", enabled);
|
||||
}
|
||||
|
||||
bool Settings::isStrictKillSwitchEnabled() const
|
||||
{
|
||||
return m_settings.value("Conf/strictKillSwitchEnabled", false).toBool();
|
||||
return value("Conf/strictKillSwitchEnabled", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::setStrictKillSwitchEnabled(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/strictKillSwitchEnabled", enabled);
|
||||
setValue("Conf/strictKillSwitchEnabled", enabled);
|
||||
}
|
||||
|
||||
QString Settings::getInstallationUuid(const bool needCreate)
|
||||
{
|
||||
auto uuid = m_settings.value("Conf/installationUuid", "").toString();
|
||||
auto uuid = value("Conf/installationUuid", "").toString();
|
||||
if (needCreate && uuid.isEmpty()) {
|
||||
uuid = QUuid::createUuid().toString();
|
||||
|
||||
@@ -475,7 +476,7 @@ QString Settings::getInstallationUuid(const bool needCreate)
|
||||
|
||||
void Settings::setInstallationUuid(const QString &uuid)
|
||||
{
|
||||
m_settings.setValue("Conf/installationUuid", uuid);
|
||||
setValue("Conf/installationUuid", uuid);
|
||||
}
|
||||
|
||||
ServerCredentials Settings::defaultServerCredentials() const
|
||||
@@ -496,6 +497,28 @@ ServerCredentials Settings::serverCredentials(int index) const
|
||||
return credentials;
|
||||
}
|
||||
|
||||
QVariant Settings::value(const QString &key, const QVariant &defaultValue) const
|
||||
{
|
||||
QVariant returnValue;
|
||||
if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
|
||||
returnValue = m_settings.value(key, defaultValue);
|
||||
} else {
|
||||
QMetaObject::invokeMethod(&m_settings, "value", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVariant, returnValue),
|
||||
Q_ARG(const QString &, key), Q_ARG(const QVariant &, defaultValue));
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void Settings::setValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
|
||||
m_settings.setValue(key, value);
|
||||
} else {
|
||||
QMetaObject::invokeMethod(&m_settings, "setValue", Qt::BlockingQueuedConnection, Q_ARG(const QString &, key),
|
||||
Q_ARG(const QVariant &, value));
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::resetGatewayEndpoint()
|
||||
{
|
||||
m_gatewayEndpoint = gatewayEndpoint;
|
||||
@@ -518,50 +541,50 @@ QString Settings::getGatewayEndpoint(bool isTestPurchase)
|
||||
|
||||
bool Settings::isDevGatewayEnv(bool isTestPurchase)
|
||||
{
|
||||
return isTestPurchase ? true : m_settings.value("Conf/devGatewayEnv", false).toBool();
|
||||
return isTestPurchase ? true : value("Conf/devGatewayEnv", false).toBool();
|
||||
}
|
||||
|
||||
void Settings::toggleDevGatewayEnv(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/devGatewayEnv", enabled);
|
||||
setValue("Conf/devGatewayEnv", enabled);
|
||||
}
|
||||
|
||||
bool Settings::isHomeAdLabelVisible()
|
||||
{
|
||||
return m_settings.value("Conf/homeAdLabelVisible", true).toBool();
|
||||
return value("Conf/homeAdLabelVisible", true).toBool();
|
||||
}
|
||||
|
||||
void Settings::disableHomeAdLabel()
|
||||
{
|
||||
m_settings.setValue("Conf/homeAdLabelVisible", false);
|
||||
setValue("Conf/homeAdLabelVisible", false);
|
||||
}
|
||||
|
||||
bool Settings::isPremV1MigrationReminderActive()
|
||||
{
|
||||
return m_settings.value("Conf/premV1MigrationReminderActive", true).toBool();
|
||||
return value("Conf/premV1MigrationReminderActive", true).toBool();
|
||||
}
|
||||
|
||||
void Settings::disablePremV1MigrationReminder()
|
||||
{
|
||||
m_settings.setValue("Conf/premV1MigrationReminderActive", false);
|
||||
setValue("Conf/premV1MigrationReminderActive", false);
|
||||
}
|
||||
|
||||
QStringList Settings::allowedDnsServers() const
|
||||
{
|
||||
return m_settings.value("Conf/allowedDnsServers").toStringList();
|
||||
return value("Conf/allowedDnsServers").toStringList();
|
||||
}
|
||||
|
||||
void Settings::setAllowedDnsServers(const QStringList &servers)
|
||||
{
|
||||
m_settings.setValue("Conf/allowedDnsServers", servers);
|
||||
setValue("Conf/allowedDnsServers", servers);
|
||||
}
|
||||
|
||||
QStringList Settings::readNewsIds() const
|
||||
{
|
||||
return m_settings.value("News/readIds").toStringList();
|
||||
return value("News/readIds").toStringList();
|
||||
}
|
||||
|
||||
void Settings::setReadNewsIds(const QStringList &ids)
|
||||
{
|
||||
m_settings.setValue("News/readIds", ids);
|
||||
setValue("News/readIds", ids);
|
||||
}
|
||||
|
||||
+25
-21
@@ -29,11 +29,11 @@ public:
|
||||
|
||||
QJsonArray serversArray() const
|
||||
{
|
||||
return QJsonDocument::fromJson(m_settings.value("Servers/serversList").toByteArray()).array();
|
||||
return QJsonDocument::fromJson(value("Servers/serversList").toByteArray()).array();
|
||||
}
|
||||
void setServersArray(const QJsonArray &servers)
|
||||
{
|
||||
m_settings.setValue("Servers/serversList", QJsonDocument(servers).toJson());
|
||||
setValue("Servers/serversList", QJsonDocument(servers).toJson());
|
||||
}
|
||||
|
||||
// Servers section
|
||||
@@ -45,11 +45,11 @@ public:
|
||||
|
||||
int defaultServerIndex() const
|
||||
{
|
||||
return m_settings.value("Servers/defaultServerIndex", 0).toInt();
|
||||
return value("Servers/defaultServerIndex", 0).toInt();
|
||||
}
|
||||
void setDefaultServer(int index)
|
||||
{
|
||||
m_settings.setValue("Servers/defaultServerIndex", index);
|
||||
setValue("Servers/defaultServerIndex", index);
|
||||
}
|
||||
QJsonObject defaultServer() const
|
||||
{
|
||||
@@ -78,34 +78,34 @@ public:
|
||||
// App settings section
|
||||
bool isAutoConnect() const
|
||||
{
|
||||
return m_settings.value("Conf/autoConnect", false).toBool();
|
||||
return value("Conf/autoConnect", false).toBool();
|
||||
}
|
||||
void setAutoConnect(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/autoConnect", enabled);
|
||||
setValue("Conf/autoConnect", enabled);
|
||||
}
|
||||
|
||||
bool isStartMinimized() const
|
||||
{
|
||||
return m_settings.value("Conf/startMinimized", false).toBool();
|
||||
return value("Conf/startMinimized", false).toBool();
|
||||
}
|
||||
void setStartMinimized(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/startMinimized", enabled);
|
||||
setValue("Conf/startMinimized", enabled);
|
||||
}
|
||||
|
||||
bool isNewsNotifications() const
|
||||
{
|
||||
return m_settings.value("Conf/newsNotifications", true).toBool();
|
||||
return value("Conf/newsNotifications", true).toBool();
|
||||
}
|
||||
void setNewsNotifications(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/newsNotifications", enabled);
|
||||
setValue("Conf/newsNotifications", enabled);
|
||||
}
|
||||
|
||||
bool isSaveLogs() const
|
||||
{
|
||||
return m_settings.value("Conf/saveLogs", false).toBool();
|
||||
return value("Conf/saveLogs", false).toBool();
|
||||
}
|
||||
void setSaveLogs(bool enabled);
|
||||
|
||||
@@ -122,18 +122,19 @@ public:
|
||||
QString routeModeString(RouteMode mode) const;
|
||||
|
||||
RouteMode routeMode() const;
|
||||
void setRouteMode(RouteMode mode) { m_settings.setValue("Conf/routeMode", mode); }
|
||||
void setRouteMode(RouteMode mode) { setValue("Conf/routeMode", mode); }
|
||||
|
||||
bool isSitesSplitTunnelingEnabled() const;
|
||||
void setSitesSplitTunnelingEnabled(bool enabled);
|
||||
|
||||
QVariantMap vpnSites(RouteMode mode) const
|
||||
{
|
||||
return m_settings.value("Conf/" + routeModeString(mode)).toMap();
|
||||
return value("Conf/" + routeModeString(mode)).toMap();
|
||||
}
|
||||
void setVpnSites(RouteMode mode, const QVariantMap &sites)
|
||||
{
|
||||
m_settings.setValue("Conf/" + routeModeString(mode), sites);
|
||||
setValue("Conf/" + routeModeString(mode), sites);
|
||||
m_settings.sync();
|
||||
}
|
||||
bool addVpnSite(RouteMode mode, const QString &site, const QString &ip = "");
|
||||
void addVpnSites(RouteMode mode, const QMap<QString, QString> &sites); // map <site, ip>
|
||||
@@ -146,11 +147,11 @@ public:
|
||||
|
||||
bool useAmneziaDns() const
|
||||
{
|
||||
return m_settings.value("Conf/useAmneziaDns", true).toBool();
|
||||
return value("Conf/useAmneziaDns", true).toBool();
|
||||
}
|
||||
void setUseAmneziaDns(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/useAmneziaDns", enabled);
|
||||
setValue("Conf/useAmneziaDns", enabled);
|
||||
}
|
||||
|
||||
QString primaryDns() const;
|
||||
@@ -159,13 +160,13 @@ public:
|
||||
// QString primaryDns() const { return m_primaryDns; }
|
||||
void setPrimaryDns(const QString &primaryDns)
|
||||
{
|
||||
m_settings.setValue("Conf/primaryDns", primaryDns);
|
||||
setValue("Conf/primaryDns", primaryDns);
|
||||
}
|
||||
|
||||
// QString secondaryDns() const { return m_secondaryDns; }
|
||||
void setSecondaryDns(const QString &secondaryDns)
|
||||
{
|
||||
m_settings.setValue("Conf/secondaryDns", secondaryDns);
|
||||
setValue("Conf/secondaryDns", secondaryDns);
|
||||
}
|
||||
|
||||
// static constexpr char openNicNs5[] = "94.103.153.176";
|
||||
@@ -187,16 +188,16 @@ public:
|
||||
};
|
||||
void setAppLanguage(QLocale locale)
|
||||
{
|
||||
m_settings.setValue("Conf/appLanguage", locale.name());
|
||||
setValue("Conf/appLanguage", locale.name());
|
||||
};
|
||||
|
||||
bool isScreenshotsEnabled() const
|
||||
{
|
||||
return m_settings.value("Conf/screenshotsEnabled", true).toBool();
|
||||
return value("Conf/screenshotsEnabled", true).toBool();
|
||||
}
|
||||
void setScreenshotsEnabled(bool enabled)
|
||||
{
|
||||
m_settings.setValue("Conf/screenshotsEnabled", enabled);
|
||||
setValue("Conf/screenshotsEnabled", enabled);
|
||||
emit screenshotsEnabledChanged(enabled);
|
||||
}
|
||||
|
||||
@@ -254,6 +255,9 @@ signals:
|
||||
void settingsCleared();
|
||||
|
||||
private:
|
||||
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
|
||||
void setValue(const QString &key, const QVariant &value);
|
||||
|
||||
void setInstallationUuid(const QString &uuid);
|
||||
|
||||
mutable SecureQSettings m_settings;
|
||||
|
||||
+1388
-841
File diff suppressed because it is too large
Load Diff
+1402
-867
File diff suppressed because it is too large
Load Diff
+1388
-841
File diff suppressed because it is too large
Load Diff
+1391
-840
File diff suppressed because it is too large
Load Diff
@@ -199,7 +199,7 @@
|
||||
<message>
|
||||
<location filename="../ui/models/api/apiServicesModel.cpp" line="116"/>
|
||||
<source>%1 $</source>
|
||||
<translation>%1 $</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/models/api/apiServicesModel.cpp" line="118"/>
|
||||
@@ -672,32 +672,32 @@ Thank you for staying with us!</source>
|
||||
<translation>Порт</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="422"/>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="418"/>
|
||||
<source>Save</source>
|
||||
<translation>Сохранить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="431"/>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="427"/>
|
||||
<source>Save settings?</source>
|
||||
<translation>Сохранить настройки?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="432"/>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="428"/>
|
||||
<source>Only the settings for this device will be changed</source>
|
||||
<translation>Будут изменены настройки только для этого устройства</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="433"/>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="429"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="434"/>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="430"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Отменить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="438"/>
|
||||
<location filename="../ui/qml/Pages2/PageProtocolAwgClientSettings.qml" line="434"/>
|
||||
<source>Unable change settings while there is an active connection</source>
|
||||
<translation>Невозможно изменить настройки во время активного соединения</translation>
|
||||
</message>
|
||||
@@ -1651,7 +1651,7 @@ Thank you for staying with us!</source>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="204"/>
|
||||
<source>mailto:support@amnezia.org</source>
|
||||
<translation>mailto:support@amnezia.org</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="211"/>
|
||||
@@ -1775,72 +1775,72 @@ Thank you for staying with us!</source>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="22"/>
|
||||
<source>Windows</source>
|
||||
<translation>Windows</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="29"/>
|
||||
<source>macOS</source>
|
||||
<translation>macOS</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="36"/>
|
||||
<source>Android</source>
|
||||
<translation>Android</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="43"/>
|
||||
<source>AndroidTV</source>
|
||||
<translation>Android TV</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="50"/>
|
||||
<source>iOS</source>
|
||||
<translation>iOS</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="57"/>
|
||||
<source>Linux</source>
|
||||
<translation>Linux</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="64"/>
|
||||
<source>Routers</source>
|
||||
<translation>Маршрутизаторы</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="23"/>
|
||||
<source>documentation/instructions/connect-amnezia-premium#windows</source>
|
||||
<translation>documentation/instructions/connect-amnezia-premium#windows</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="30"/>
|
||||
<source>documentation/instructions/connect-amnezia-premium#macos</source>
|
||||
<translation>documentation/instructions/connect-amnezia-premium#macos</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="37"/>
|
||||
<source>documentation/instructions/connect-amnezia-premium#android</source>
|
||||
<translation>documentation/instructions/connect-amnezia-premium#android</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="44"/>
|
||||
<source>documentation/instructions/android_tv_connect/</source>
|
||||
<translation>documentation/instructions/android_tv_connect/</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="51"/>
|
||||
<source>documentation/instructions/connect-amnezia-premium#ios</source>
|
||||
<translation>documentation/instructions/connect-amnezia-premium#ios</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="58"/>
|
||||
<source>documentation/instructions/connect-amnezia-premium#linux</source>
|
||||
<translation>documentation/instructions/connect-amnezia-premium#linux</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="65"/>
|
||||
<source>documentation/instructions/connect-amnezia-premium#routers</source>
|
||||
<translation>documentation/instructions/connect-amnezia-premium#routers</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiInstructions.qml" line="101"/>
|
||||
@@ -2111,7 +2111,7 @@ Thank you for staying with us!</source>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiSupport.qml" line="22"/>
|
||||
<source>Telegram</source>
|
||||
<translation>Telegram</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiSupport.qml" line="30"/>
|
||||
@@ -2141,7 +2141,7 @@ Thank you for staying with us!</source>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiSupport.qml" line="110"/>
|
||||
<source>Support tag</source>
|
||||
<translation>Идентификатор поддержки</translation>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApiSupport.qml" line="120"/>
|
||||
@@ -2272,12 +2272,12 @@ Thank you for staying with us!</source>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="180"/>
|
||||
<source>News Notification</source>
|
||||
<translation>Уведомления о новостях</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="181"/>
|
||||
<source>Show a notification icon for unread news</source>
|
||||
<translation>Показывать значок уведомления, если есть непрочитанные новости</translation>
|
||||
<source>Show notification icon when has unread news</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="221"/>
|
||||
@@ -3115,17 +3115,17 @@ Thank you for staying with us!</source>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml" line="113"/>
|
||||
<source>Charged to your Apple ID at confirmation. Renews automatically unless auto-renew is turned off at least 24 hours before period end. Manage in Apple ID settings.</source>
|
||||
<translation>Списание с Apple ID при подтверждении. Продление автоматическое, если автопродление не отключено минимум за 24 часа до окончания периода. Управление в настройках Apple ID.</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml" line="125"/>
|
||||
<source>Subscribe Now</source>
|
||||
<translation>Подписаться сейчас</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml" line="158"/>
|
||||
<source>By continuing, you agree to the <a href="%1" style="color: #FBB26A;">Terms of Use</a> and <a href="%2" style="color: #FBB26A;">Privacy Policy</a></source>
|
||||
<translation>Продолжая, вы соглашаетесь с <a href="%1" style="color: #FBB26A;">Условиями использования</a> и <a href="%2" style="color: #FBB26A;">Политикой конфиденциальности</a></translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageSetupWizardApiServiceInfo.qml" line="186"/>
|
||||
@@ -3697,7 +3697,7 @@ Thank you for staying with us!</source>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="270"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="572"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="566"/>
|
||||
<source>Users</source>
|
||||
<translation>Пользователи</translation>
|
||||
</message>
|
||||
@@ -3707,72 +3707,72 @@ Thank you for staying with us!</source>
|
||||
<translation>Имя пользователя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="588"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="582"/>
|
||||
<source>Search</source>
|
||||
<translation>Поиск</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="717"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="711"/>
|
||||
<source>Creation date: %1</source>
|
||||
<translation>Дата создания: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="729"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="723"/>
|
||||
<source>Latest handshake: %1</source>
|
||||
<translation>Последнее рукопожатие: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="741"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="735"/>
|
||||
<source>Data received: %1</source>
|
||||
<translation>Получено данных: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="753"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="747"/>
|
||||
<source>Data sent: %1</source>
|
||||
<translation>Отправлено данных: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="763"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="757"/>
|
||||
<source>Allowed IPs: %1</source>
|
||||
<translation>Разрешенные подсети: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="778"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="772"/>
|
||||
<source>Rename</source>
|
||||
<translation>Переименовать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="803"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="797"/>
|
||||
<source>Client name</source>
|
||||
<translation>Имя клиента</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="808"/>
|
||||
<source>Save</source>
|
||||
<translation>Сохранить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="850"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="844"/>
|
||||
<source>Revoke</source>
|
||||
<translation>Отозвать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="853"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="847"/>
|
||||
<source>Revoke the config for a user - %1?</source>
|
||||
<translation>Отозвать конфигурацию для пользователя - %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="854"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="848"/>
|
||||
<source>The user will no longer be able to connect to your server.</source>
|
||||
<translation>Пользователь больше не сможет подключаться к вашему серверу.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="855"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="849"/>
|
||||
<source>Continue</source>
|
||||
<translation>Продолжить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="856"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="850"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Отменить</translation>
|
||||
</message>
|
||||
@@ -3795,7 +3795,7 @@ Thank you for staying with us!</source>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="220"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="554"/>
|
||||
<location filename="../ui/qml/Pages2/PageShare.qml" line="548"/>
|
||||
<source>Share</source>
|
||||
<translation>Поделиться</translation>
|
||||
</message>
|
||||
@@ -4241,7 +4241,7 @@ Thank you for staying with us!</source>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="32"/>
|
||||
<source>Server error: Linux kernel is too old</source>
|
||||
<translation>Ошибка сервера: ядро Linux слишком старое</translation>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../core/errorstrings.cpp" line="35"/>
|
||||
@@ -5020,47 +5020,47 @@ FileZilla или другие SFTP-клиенты, а также смонтир
|
||||
<context>
|
||||
<name>SitesController</name>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="22"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="24"/>
|
||||
<source>Hostname not look like ip adress or domain name</source>
|
||||
<translation>Имя хоста не похоже на IP-адрес или доменное имя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="52"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="66"/>
|
||||
<source>New site added: %1</source>
|
||||
<translation>Добавлен новый сайт: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="61"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="78"/>
|
||||
<source>Site removed: %1</source>
|
||||
<translation>Сайт удален: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="68"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="85"/>
|
||||
<source>Site list cleared!</source>
|
||||
<translation>Список сайтов очищен!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="75"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="92"/>
|
||||
<source>Can't open file: %1</source>
|
||||
<translation>Невозможно открыть файл: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="81"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="98"/>
|
||||
<source>Failed to parse JSON data from file: %1</source>
|
||||
<translation>Не удалось разобрать JSON-данные из файла: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="86"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="103"/>
|
||||
<source>The JSON data is not an array in file: %1</source>
|
||||
<translation>JSON-данные не являются массивом в файле: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="114"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="133"/>
|
||||
<source>Import completed</source>
|
||||
<translation>Импорт завершен</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="133"/>
|
||||
<location filename="../ui/controllers/sitesController.cpp" line="152"/>
|
||||
<source>Export completed</source>
|
||||
<translation>Экспорт завершен</translation>
|
||||
</message>
|
||||
|
||||
+1408
-865
File diff suppressed because it is too large
Load Diff
+1396
-853
File diff suppressed because it is too large
Load Diff
+1402
-875
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QImage>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include "core/controllers/vpnConfigurationController.h"
|
||||
#include "core/qrCodeUtils.h"
|
||||
#include "core/serialization/serialization.h"
|
||||
@@ -169,7 +170,8 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
|
||||
m_config.append(line + "\n");
|
||||
}
|
||||
|
||||
m_qrCodes = qrCodeUtils::generateQrCodeImageSeries(m_config.toUtf8());
|
||||
auto qr = qrCodeUtils::generateQrCode(m_config.toUtf8());
|
||||
m_qrCodes << qrCodeUtils::svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
||||
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
@@ -189,7 +191,8 @@ void ExportController::generateAwgConfig(const QString &clientName)
|
||||
m_config.append(line + "\n");
|
||||
}
|
||||
|
||||
m_qrCodes = qrCodeUtils::generateQrCodeImageSeries(m_config.toUtf8());
|
||||
auto qr = qrCodeUtils::generateQrCode(m_config.toUtf8());
|
||||
m_qrCodes << qrCodeUtils::svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
|
||||
|
||||
emit exportConfigChanged();
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||
|
||||
int s1 = QRandomGenerator::global()->bounded(15, 150);
|
||||
int s2 = QRandomGenerator::global()->bounded(15, 150);
|
||||
int s3 = QRandomGenerator::global()->bounded(1, 64);
|
||||
int s4 = QRandomGenerator::global()->bounded(1, 20);
|
||||
int s3 = QRandomGenerator::global()->bounded(0, 64);
|
||||
int s4 = QRandomGenerator::global()->bounded(0, 20);
|
||||
|
||||
// Ensure all values are unique and don't create equal packet sizes
|
||||
QSet<int> usedValues;
|
||||
@@ -97,12 +97,12 @@ void InstallController::install(DockerContainer container, int port, TransportPr
|
||||
|
||||
while (usedValues.contains(s3) || s1 + AwgConstant::messageInitiationSize == s3 + AwgConstant::messageCookieReplySize
|
||||
|| s2 + AwgConstant::messageResponseSize == s3 + AwgConstant::messageCookieReplySize) {
|
||||
s3 = QRandomGenerator::global()->bounded(1, 64);
|
||||
s3 = QRandomGenerator::global()->bounded(0, 64);
|
||||
}
|
||||
usedValues.insert(s3);
|
||||
|
||||
while (usedValues.contains(s4)) {
|
||||
s4 = QRandomGenerator::global()->bounded(1, 20);
|
||||
s4 = QRandomGenerator::global()->bounded(0, 20);
|
||||
}
|
||||
|
||||
QString initPacketJunkSize = QString::number(s1);
|
||||
@@ -987,94 +987,79 @@ void InstallController::addEmptyServer()
|
||||
emit installServerFinished(tr("Server added successfully"));
|
||||
}
|
||||
|
||||
void InstallController::validateConfig()
|
||||
bool InstallController::isConfigValid()
|
||||
{
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
QJsonObject serverConfigObject = m_serversModel->getServerConfig(serverIndex);
|
||||
|
||||
if (apiUtils::isServerFromApi(serverConfigObject)) {
|
||||
emit configValidated(true);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
|
||||
emit noInstalledContainers();
|
||||
emit configValidated(false);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
|
||||
|
||||
if (container == DockerContainer::None) {
|
||||
emit installationErrorOccurred(ErrorCode::NoInstalledContainersError);
|
||||
emit configValidated(false);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
||||
|
||||
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
|
||||
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
|
||||
QSharedPointer<ServerController> serverController(new ServerController(m_settings));
|
||||
|
||||
auto isProtocolConfigExists = [](const QJsonObject &containerConfig, const DockerContainer container) {
|
||||
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||
QString protocolConfig =
|
||||
containerConfig.value(ProtocolProps::protoToString(protocol)).toObject().value(config_key::last_config).toString();
|
||||
QFutureWatcher<ErrorCode> watcher;
|
||||
|
||||
if (protocolConfig.isEmpty()) {
|
||||
return false;
|
||||
QFuture<ErrorCode> future = QtConcurrent::run([this, container, &credentials, &containerConfig, &serverController]() {
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
|
||||
auto isProtocolConfigExists = [](const QJsonObject &containerConfig, const DockerContainer container) {
|
||||
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||
QString protocolConfig =
|
||||
containerConfig.value(ProtocolProps::protoToString(protocol)).toObject().value(config_key::last_config).toString();
|
||||
|
||||
if (protocolConfig.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!isProtocolConfigExists(containerConfig, container)) {
|
||||
VpnConfigurationsController vpnConfigurationController(m_settings, serverController);
|
||||
errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container, containerConfig);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
m_serversModel->updateContainerConfig(container, containerConfig);
|
||||
|
||||
errorCode = m_clientManagementModel->appendClient(container, credentials, containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
return errorCode;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
return errorCode;
|
||||
});
|
||||
|
||||
if (isProtocolConfigExists(containerConfig, container)) {
|
||||
emit configValidated(true);
|
||||
return;
|
||||
QEventLoop wait;
|
||||
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
|
||||
watcher.setFuture(future);
|
||||
wait.exec();
|
||||
|
||||
ErrorCode errorCode = watcher.result();
|
||||
|
||||
if (errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct ValidationResult {
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
QJsonObject containerConfig;
|
||||
};
|
||||
|
||||
QFuture<ValidationResult> future =
|
||||
QtConcurrent::run([settings = m_settings, serverController, credentials, containerConfig, container]() mutable {
|
||||
ValidationResult result;
|
||||
result.containerConfig = containerConfig;
|
||||
|
||||
VpnConfigurationsController vpnConfigurationController(settings, serverController);
|
||||
result.errorCode = vpnConfigurationController.createProtocolConfigForContainer(credentials, container,
|
||||
result.containerConfig);
|
||||
return result;
|
||||
});
|
||||
|
||||
auto *watcher = new QFutureWatcher<ValidationResult>(this);
|
||||
connect(watcher, &QFutureWatcher<ValidationResult>::finished, this,
|
||||
[this, watcher, container, credentials, serverController]() {
|
||||
auto result = watcher->result();
|
||||
watcher->deleteLater();
|
||||
|
||||
if (result.errorCode != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(result.errorCode);
|
||||
emit configValidated(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_serversModel->updateContainerConfig(container, result.containerConfig);
|
||||
|
||||
ErrorCode appendError = m_clientManagementModel->appendClient(
|
||||
container, credentials, result.containerConfig,
|
||||
QString("Admin [%1]").arg(QSysInfo::prettyProductName()), serverController);
|
||||
|
||||
if (appendError != ErrorCode::NoError) {
|
||||
emit installationErrorOccurred(appendError);
|
||||
emit configValidated(false);
|
||||
return;
|
||||
}
|
||||
|
||||
emit configValidated(true);
|
||||
});
|
||||
watcher->setFuture(future);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstallController::isUpdateDockerContainerRequired(const DockerContainer container, const QJsonObject &oldConfig,
|
||||
@@ -1085,7 +1070,7 @@ bool InstallController::isUpdateDockerContainerRequired(const DockerContainer co
|
||||
const QJsonObject &oldProtoConfig = oldConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||
const QJsonObject &newProtoConfig = newConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||
|
||||
if (ContainerProps::isAwgContainer(container)) {
|
||||
if (container == DockerContainer::Awg2) {
|
||||
const AwgConfig oldConfig(oldProtoConfig);
|
||||
const AwgConfig newConfig(newProtoConfig);
|
||||
|
||||
|
||||
@@ -50,10 +50,9 @@ public slots:
|
||||
|
||||
void addEmptyServer();
|
||||
|
||||
void validateConfig();
|
||||
bool isConfigValid();
|
||||
|
||||
signals:
|
||||
void configValidated(bool isValid);
|
||||
void installContainerFinished(const QString &finishMessage, bool isServiceInstall);
|
||||
void installServerFinished(const QString &finishMessage);
|
||||
|
||||
|
||||
@@ -158,7 +158,6 @@ void SettingsController::clearLogs()
|
||||
|
||||
qInfo().noquote() << QString("Started %1 version %2 %3").arg(APPLICATION_NAME, APP_VERSION, GIT_COMMIT_HASH);
|
||||
qInfo().noquote() << QString("%1 (%2)").arg(QSysInfo::prettyProductName(), QSysInfo::currentCpuArchitecture());
|
||||
qInfo().noquote() << QString("SSL backend: %1").arg(QSslSocket::sslLibraryVersionString());
|
||||
}
|
||||
|
||||
void SettingsController::backupAppConfig(const QString &fileName)
|
||||
@@ -178,11 +177,12 @@ void SettingsController::backupAppConfig(const QString &fileName)
|
||||
|
||||
void SettingsController::restoreAppConfig(const QString &fileName)
|
||||
{
|
||||
QByteArray data;
|
||||
if (!SystemController::readFile(fileName, data)) {
|
||||
emit changeSettingsErrorOccurred(tr("Can't open file: %1").arg(fileName));
|
||||
return;
|
||||
}
|
||||
QFile file(fileName);
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
|
||||
restoreAppConfigFromData(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
#include "systemController.h"
|
||||
#include "core/networkUtilities.h"
|
||||
|
||||
SitesController::SitesController(const std::shared_ptr<Settings> &settings, const QSharedPointer<SitesModel> &sitesModel, QObject *parent)
|
||||
: QObject(parent), m_settings(settings), m_sitesModel(sitesModel)
|
||||
SitesController::SitesController(const std::shared_ptr<Settings> &settings,
|
||||
const QSharedPointer<VpnConnection> &vpnConnection,
|
||||
const QSharedPointer<SitesModel> &sitesModel, QObject *parent)
|
||||
: QObject(parent), m_settings(settings), m_vpnConnection(vpnConnection), m_sitesModel(sitesModel)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,20 +34,32 @@ void SitesController::addSite(QString hostname)
|
||||
hostname = hostname.split("/", Qt::SkipEmptyParts).first();
|
||||
}
|
||||
|
||||
const auto &resolveCallback = [this](const QHostInfo &hostInfo) {
|
||||
const auto &processSite = [this](const QString &hostname, const QString &ip) {
|
||||
m_sitesModel->addSite(hostname, ip);
|
||||
|
||||
if (!ip.isEmpty()) {
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "addRoutes", Qt::QueuedConnection,
|
||||
Q_ARG(QStringList, QStringList() << ip));
|
||||
} else if (NetworkUtilities::ipAddressWithSubnetRegExp().exactMatch(hostname)) {
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "addRoutes", Qt::QueuedConnection,
|
||||
Q_ARG(QStringList, QStringList() << hostname));
|
||||
}
|
||||
};
|
||||
|
||||
const auto &resolveCallback = [this, processSite](const QHostInfo &hostInfo) {
|
||||
const QList<QHostAddress> &addresses = hostInfo.addresses();
|
||||
for (const QHostAddress &addr : hostInfo.addresses()) {
|
||||
if (addr.protocol() == QAbstractSocket::NetworkLayerProtocol::IPv4Protocol) {
|
||||
m_sitesModel->addSite(hostInfo.hostName(), addr.toString());
|
||||
processSite(hostInfo.hostName(), addr.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (NetworkUtilities::ipAddressWithSubnetRegExp().exactMatch(hostname)) {
|
||||
m_sitesModel->addSite(hostname, "");
|
||||
processSite(hostname, "");
|
||||
} else {
|
||||
m_sitesModel->addSite(hostname, "");
|
||||
processSite(hostname, "");
|
||||
QHostInfo::lookupHost(hostname, this, resolveCallback);
|
||||
}
|
||||
|
||||
@@ -58,6 +72,9 @@ void SitesController::removeSite(int index)
|
||||
auto hostname = m_sitesModel->data(modelIndex, SitesModel::Roles::UrlRole).toString();
|
||||
m_sitesModel->removeSite(modelIndex);
|
||||
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "deleteRoutes", Qt::QueuedConnection,
|
||||
Q_ARG(QStringList, QStringList() << hostname));
|
||||
|
||||
emit finished(tr("Site removed: %1").arg(hostname));
|
||||
}
|
||||
|
||||
@@ -111,6 +128,8 @@ void SitesController::importSites(const QString &fileName, bool replaceExisting)
|
||||
|
||||
m_sitesModel->addSites(sites, replaceExisting);
|
||||
|
||||
QMetaObject::invokeMethod(m_vpnConnection.get(), "addRoutes", Qt::QueuedConnection, Q_ARG(QStringList, ips));
|
||||
|
||||
emit finished(tr("Import completed"));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ class SitesController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SitesController(const std::shared_ptr<Settings> &settings, const QSharedPointer<SitesModel> &sitesModel,
|
||||
QObject *parent = nullptr);
|
||||
explicit SitesController(const std::shared_ptr<Settings> &settings,
|
||||
const QSharedPointer<VpnConnection> &vpnConnection,
|
||||
const QSharedPointer<SitesModel> &sitesModel, QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void addSite(QString hostname);
|
||||
@@ -30,6 +31,8 @@ signals:
|
||||
|
||||
private:
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||
QSharedPointer<SitesModel> m_sitesModel;
|
||||
};
|
||||
|
||||
|
||||
@@ -141,12 +141,10 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
|
||||
serverProtocolConfig.value(config_key::initPacketJunkSize).toString(protocols::awg::defaultInitPacketJunkSize);
|
||||
m_serverProtocolConfig[config_key::responsePacketJunkSize] =
|
||||
serverProtocolConfig.value(config_key::responsePacketJunkSize).toString(protocols::awg::defaultResponsePacketJunkSize);
|
||||
if (protocolVersion == protocols::awg::awgV2) {
|
||||
m_serverProtocolConfig[config_key::cookieReplyPacketJunkSize] =
|
||||
serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
|
||||
m_serverProtocolConfig[config_key::transportPacketJunkSize] =
|
||||
serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
|
||||
}
|
||||
m_serverProtocolConfig[config_key::cookieReplyPacketJunkSize] =
|
||||
serverProtocolConfig.value(config_key::cookieReplyPacketJunkSize).toString(protocols::awg::defaultCookieReplyPacketJunkSize);
|
||||
m_serverProtocolConfig[config_key::transportPacketJunkSize] =
|
||||
serverProtocolConfig.value(config_key::transportPacketJunkSize).toString(protocols::awg::defaultTransportPacketJunkSize);
|
||||
m_serverProtocolConfig[config_key::initPacketMagicHeader] =
|
||||
serverProtocolConfig.value(config_key::initPacketMagicHeader).toString(protocols::awg::defaultInitPacketMagicHeader);
|
||||
m_serverProtocolConfig[config_key::responsePacketMagicHeader] =
|
||||
|
||||
@@ -8,10 +8,9 @@ Item {
|
||||
id: root
|
||||
|
||||
property StackView stackView: StackView.view
|
||||
property bool enableTimer: true
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible && enableTimer) {
|
||||
if (visible) {
|
||||
timer.start()
|
||||
}
|
||||
}
|
||||
@@ -25,6 +24,6 @@ Item {
|
||||
FocusController.setFocusOnDefaultItem()
|
||||
}
|
||||
repeat: false // Stop the timer after one trigger
|
||||
running: enableTimer // Start the timer
|
||||
running: true // Start the timer
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,8 +330,6 @@ PageType {
|
||||
AwgTextField {
|
||||
id: cookieReplyPacketJunkSizeTextField
|
||||
|
||||
visible: isAwg2
|
||||
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
@@ -344,8 +342,6 @@ PageType {
|
||||
AwgTextField {
|
||||
id: transportPacketJunkSizeTextField
|
||||
|
||||
visible: isAwg2
|
||||
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ PageType {
|
||||
Layout.margins: 16
|
||||
|
||||
text: qsTr("News Notification")
|
||||
descriptionText: qsTr("Show a notification icon for unread news")
|
||||
descriptionText: qsTr("Show notification icon when has unread news")
|
||||
|
||||
checked: SettingsController.isNewsNotificationsEnabled()
|
||||
onToggled: function() {
|
||||
|
||||
@@ -13,7 +13,6 @@ import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
enableTimer: (SettingsController.isOnTv()) ? false : true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
@@ -46,22 +45,4 @@ PageType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 250
|
||||
running: SettingsController.isOnTv()
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
startButton.forceActiveFocus()
|
||||
if (startButton.activeFocus) {
|
||||
running = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible && SettingsController.isOnTv()) {
|
||||
startButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,13 +505,7 @@ PageType {
|
||||
exportTypeSelector.currentIndex = 0
|
||||
}
|
||||
selectedIndex = exportTypeSelector.currentIndex
|
||||
if (model.length > 0 && model[selectedIndex] && model[selectedIndex].name !== undefined) {
|
||||
exportTypeSelectorListView.selectedText = model[selectedIndex].name
|
||||
exportTypeSelector.text = model[selectedIndex].name
|
||||
} else {
|
||||
exportTypeSelectorListView.selectedText = ""
|
||||
exportTypeSelector.text = ""
|
||||
}
|
||||
exportTypeSelector.text = selectedText
|
||||
}
|
||||
|
||||
rootWidth: root.width
|
||||
|
||||
@@ -278,6 +278,7 @@ PageType {
|
||||
}
|
||||
|
||||
Keys.onPressed: function(event) {
|
||||
console.debug(">>>> ", event.key, " Event is caught by StartPage")
|
||||
switch (event.key) {
|
||||
case Qt.Key_Tab:
|
||||
case Qt.Key_Down:
|
||||
@@ -303,7 +304,7 @@ PageType {
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
|
||||
// Also adjust TabBar position when keyboard appears (Android 14+ workaround)
|
||||
anchors.bottomMargin: SettingsController.imeHeight
|
||||
|
||||
|
||||
@@ -56,11 +56,6 @@ Window {
|
||||
PageController.closeWindow()
|
||||
}
|
||||
|
||||
onSceneGraphError: function(error, message) {
|
||||
// Prevent qFatal crash on Android when EGL context is lost
|
||||
console.warn("Scene graph error:", error, message)
|
||||
}
|
||||
|
||||
title: "AmneziaVPN"
|
||||
|
||||
Item { // This item is needed for focus handling
|
||||
|
||||
@@ -39,7 +39,7 @@ VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent
|
||||
{
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
m_checkTimer.setInterval(1000);
|
||||
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::setConnectionState);
|
||||
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged);
|
||||
connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged);
|
||||
#endif
|
||||
}
|
||||
@@ -464,7 +464,7 @@ void VpnConnection::disconnectFromVpn()
|
||||
*connection = connect(AndroidController::instance(), &AndroidController::vpnStateChanged, this,
|
||||
[this, connection](AndroidController::ConnectionState state) {
|
||||
if (state == AndroidController::ConnectionState::DISCONNECTED) {
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
onConnectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
disconnect(*connection);
|
||||
delete connection;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
find_program(CONAN_COMMAND "conan" REQUIRED HINTS /opt/homebrew/bin)
|
||||
|
||||
file(GLOB_RECURSE LOCAL_RECIPES "${CMAKE_SOURCE_DIR}/recipes/*/conanfile.py")
|
||||
foreach(RECIPE ${LOCAL_RECIPES})
|
||||
get_filename_component(RECIPE_DIR ${RECIPE} DIRECTORY)
|
||||
execute_process(
|
||||
COMMAND ${CONAN_COMMAND} export ${RECIPE_DIR}
|
||||
)
|
||||
endforeach()
|
||||
@@ -0,0 +1,722 @@
|
||||
# The MIT License (MIT)
|
||||
#
|
||||
# Copyright (c) 2024 JFrog
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
set(CONAN_MINIMUM_VERSION 2.0.5)
|
||||
|
||||
# Create a new policy scope and set the minimum required cmake version so the
|
||||
# features behind a policy setting like if(... IN_LIST ...) behaves as expected
|
||||
# even if the parent project does not specify a minimum cmake version or a minimum
|
||||
# version less than this module requires (e.g. 3.0) before the first project() call.
|
||||
# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html)
|
||||
#
|
||||
# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only
|
||||
# affects the current policy scope, i.e. between the PUSH and POP in this case.
|
||||
#
|
||||
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack
|
||||
cmake_policy(PUSH)
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
|
||||
function(detect_os os os_api_level os_sdk os_subsystem os_version)
|
||||
# it could be cross compilation
|
||||
message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}")
|
||||
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(${os} Macos PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
|
||||
set(${os} Neutrino PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
|
||||
set(${os} Windows PARENT_SCOPE)
|
||||
set(${os_subsystem} cygwin PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS")
|
||||
set(${os} Windows PARENT_SCOPE)
|
||||
set(${os_subsystem} msys2 PARENT_SCOPE)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
||||
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L17C1-L17C34
|
||||
set(${os} Emscripten PARENT_SCOPE)
|
||||
else()
|
||||
set(${os} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
if(DEFINED ANDROID_PLATFORM)
|
||||
string(REGEX MATCH "[0-9]+" _os_api_level ${ANDROID_PLATFORM})
|
||||
elseif(DEFINED CMAKE_SYSTEM_VERSION)
|
||||
set(_os_api_level ${CMAKE_SYSTEM_VERSION})
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: android api level=${_os_api_level}")
|
||||
set(${os_api_level} ${_os_api_level} PARENT_SCOPE)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS")
|
||||
# CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja
|
||||
# generators, but just has the original input string for Xcode.
|
||||
if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT})
|
||||
set(_os_sdk ${CMAKE_OSX_SYSROOT})
|
||||
else()
|
||||
if(CMAKE_OSX_SYSROOT MATCHES Simulator)
|
||||
set(apple_platform_suffix simulator)
|
||||
else()
|
||||
set(apple_platform_suffix os)
|
||||
endif()
|
||||
if(CMAKE_OSX_SYSROOT MATCHES AppleTV)
|
||||
set(_os_sdk "appletv${apple_platform_suffix}")
|
||||
elseif(CMAKE_OSX_SYSROOT MATCHES iPhone)
|
||||
set(_os_sdk "iphone${apple_platform_suffix}")
|
||||
elseif(CMAKE_OSX_SYSROOT MATCHES Watch)
|
||||
set(_os_sdk "watch${apple_platform_suffix}")
|
||||
endif()
|
||||
endif()
|
||||
if(DEFINED os_sdk)
|
||||
message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}")
|
||||
set(${os_sdk} ${_os_sdk} PARENT_SCOPE)
|
||||
endif()
|
||||
if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
|
||||
message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
set(${os_version} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_arch arch)
|
||||
# CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one.
|
||||
# Therefore this code only finds one. If the recipes support multiple architectures, the
|
||||
# build will work. Otherwise, there will be a linker error for the missing architecture(s).
|
||||
if(DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}")
|
||||
list(LENGTH apple_arch_list apple_arch_count)
|
||||
if(apple_arch_count GREATER 1)
|
||||
message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.")
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
|
||||
set(host_arch ${CMAKE_OSX_ARCHITECTURES})
|
||||
elseif(MSVC)
|
||||
set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})
|
||||
else()
|
||||
set(host_arch ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
if(host_arch MATCHES "aarch64|arm64|ARM64")
|
||||
list(APPEND _arch armv8)
|
||||
endif()
|
||||
if(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7")
|
||||
list(APPEND _arch armv7)
|
||||
endif()
|
||||
if(host_arch MATCHES armv7s)
|
||||
list(APPEND _arch armv7s)
|
||||
endif()
|
||||
if(host_arch MATCHES "i686|i386|X86")
|
||||
list(APPEND _arch x86)
|
||||
endif()
|
||||
if(host_arch MATCHES "AMD64|amd64|x86_64|x64")
|
||||
list(APPEND _arch x86_64)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
# https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L294C1-L294C80
|
||||
list(APPEND _arch wasm)
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: cmake_system_processor=${_arch}")
|
||||
list(JOIN _arch "|" _arch)
|
||||
set(${arch} ${_arch} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_cxx_standard compiler cxx_standard)
|
||||
set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
|
||||
if(CMAKE_CXX_EXTENSIONS)
|
||||
if(compiler STREQUAL "msvc")
|
||||
set(${cxx_standard} "${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
|
||||
else()
|
||||
set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(detect_gnu_libstdcxx)
|
||||
# _conan_is_gnu_libstdcxx true if GNU libstdc++
|
||||
check_cxx_source_compiles("
|
||||
#include <cstddef>
|
||||
#if !defined(__GLIBCXX__) && !defined(__GLIBCPP__)
|
||||
static_assert(false);
|
||||
#endif
|
||||
int main(){}" _conan_is_gnu_libstdcxx)
|
||||
|
||||
# _conan_gnu_libstdcxx_is_cxx11_abi true if C++11 ABI
|
||||
check_cxx_source_compiles("
|
||||
#include <string>
|
||||
static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\");
|
||||
int main () {}" _conan_gnu_libstdcxx_is_cxx11_abi)
|
||||
|
||||
set(_conan_gnu_libstdcxx_suffix "")
|
||||
if(_conan_gnu_libstdcxx_is_cxx11_abi)
|
||||
set(_conan_gnu_libstdcxx_suffix "11")
|
||||
endif()
|
||||
unset (_conan_gnu_libstdcxx_is_cxx11_abi)
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(detect_libcxx)
|
||||
# _conan_is_libcxx true if LLVM libc++
|
||||
check_cxx_source_compiles("
|
||||
#include <cstddef>
|
||||
#if !defined(_LIBCPP_VERSION)
|
||||
static_assert(false);
|
||||
#endif
|
||||
int main(){}" _conan_is_libcxx)
|
||||
endmacro()
|
||||
|
||||
|
||||
function(detect_lib_cxx lib_cxx)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}")
|
||||
set(${lib_cxx} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
detect_gnu_libstdcxx()
|
||||
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
|
||||
set(${lib_cxx} "libc++" PARENT_SCOPE)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
# Check for libc++
|
||||
detect_libcxx()
|
||||
if(_conan_is_libcxx)
|
||||
set(${lib_cxx} "libc++" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Check for libstdc++
|
||||
detect_gnu_libstdcxx()
|
||||
if(_conan_is_gnu_libstdcxx)
|
||||
set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# TODO: it would be an error if we reach this point
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
# Do nothing - compiler.runtime and compiler.runtime_type
|
||||
# should be handled separately: https://github.com/conan-io/cmake-conan/pull/516
|
||||
return()
|
||||
else()
|
||||
# TODO: unable to determine, ask user to provide a full profile file instead
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_compiler compiler compiler_version compiler_runtime compiler_runtime_type)
|
||||
if(DEFINED CMAKE_CXX_COMPILER_ID)
|
||||
set(_compiler ${CMAKE_CXX_COMPILER_ID})
|
||||
set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
|
||||
else()
|
||||
if(NOT DEFINED CMAKE_C_COMPILER_ID)
|
||||
message(FATAL_ERROR "C or C++ compiler not defined")
|
||||
endif()
|
||||
set(_compiler ${CMAKE_C_COMPILER_ID})
|
||||
set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: CMake compiler=${_compiler}")
|
||||
message(STATUS "CMake-Conan: CMake compiler version=${_compiler_version}")
|
||||
|
||||
if(_compiler MATCHES MSVC)
|
||||
set(_compiler "msvc")
|
||||
string(SUBSTRING ${MSVC_VERSION} 0 3 _compiler_version)
|
||||
# Configure compiler.runtime and compiler.runtime_type settings for MSVC
|
||||
if(CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY})
|
||||
else()
|
||||
set(_msvc_runtime_library MultiThreaded$<$<CONFIG:Debug>:Debug>DLL) # default value documented by CMake
|
||||
endif()
|
||||
|
||||
set(_KNOWN_MSVC_RUNTIME_VALUES "")
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL)
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL)
|
||||
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$<CONFIG:Debug>:Debug> MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
|
||||
|
||||
# only accept the 6 possible values, otherwise we don't don't know to map this
|
||||
if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES)
|
||||
message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings")
|
||||
endif()
|
||||
|
||||
# Runtime is "dynamic" in all cases if it ends in DLL
|
||||
if(_msvc_runtime_library MATCHES ".*DLL$")
|
||||
set(_compiler_runtime "dynamic")
|
||||
else()
|
||||
set(_compiler_runtime "static")
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: CMake compiler.runtime=${_compiler_runtime}")
|
||||
|
||||
# Only define compiler.runtime_type when explicitly requested
|
||||
# If a generator expression is used, let Conan handle it conditional on build_type
|
||||
if(NOT _msvc_runtime_library MATCHES "<CONFIG:Debug>:Debug>")
|
||||
if(_msvc_runtime_library MATCHES "Debug")
|
||||
set(_compiler_runtime_type "Debug")
|
||||
else()
|
||||
set(_compiler_runtime_type "Release")
|
||||
endif()
|
||||
message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_compiler_runtime_type}")
|
||||
endif()
|
||||
|
||||
unset(_KNOWN_MSVC_RUNTIME_VALUES)
|
||||
|
||||
elseif(_compiler MATCHES AppleClang)
|
||||
set(_compiler "apple-clang")
|
||||
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
|
||||
list(GET VERSION_LIST 0 _compiler_version)
|
||||
elseif(_compiler MATCHES Clang)
|
||||
set(_compiler "clang")
|
||||
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
|
||||
list(GET VERSION_LIST 0 _compiler_version)
|
||||
elseif(_compiler MATCHES GNU)
|
||||
set(_compiler "gcc")
|
||||
string(REPLACE "." ";" VERSION_LIST ${_compiler_version})
|
||||
list(GET VERSION_LIST 0 _compiler_version)
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: [settings] compiler=${_compiler}")
|
||||
message(STATUS "CMake-Conan: [settings] compiler.version=${_compiler_version}")
|
||||
if (_compiler_runtime)
|
||||
message(STATUS "CMake-Conan: [settings] compiler.runtime=${_compiler_runtime}")
|
||||
endif()
|
||||
if (_compiler_runtime_type)
|
||||
message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_compiler_runtime_type}")
|
||||
endif()
|
||||
|
||||
set(${compiler} ${_compiler} PARENT_SCOPE)
|
||||
set(${compiler_version} ${_compiler_version} PARENT_SCOPE)
|
||||
set(${compiler_runtime} ${_compiler_runtime} PARENT_SCOPE)
|
||||
set(${compiler_runtime_type} ${_compiler_runtime_type} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(detect_build_type build_type)
|
||||
get_property(multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(NOT multiconfig_generator)
|
||||
# Only set when we know we are in a single-configuration generator
|
||||
# Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined
|
||||
set(${build_type} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(set_conan_compiler_if_appleclang lang command output_variable)
|
||||
if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang")
|
||||
execute_process(COMMAND xcrun --find ${command}
|
||||
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path)
|
||||
cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path)
|
||||
if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}")
|
||||
set(${output_variable} "")
|
||||
endif()
|
||||
unset(_xcrun_out)
|
||||
unset(_xcrun_toolchain_path)
|
||||
unset(_compiler_parent_path)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(append_compiler_executables_configuration)
|
||||
set(_conan_c_compiler "")
|
||||
set(_conan_cpp_compiler "")
|
||||
set(_conan_rc_compiler "")
|
||||
set(_conan_compilers_list "")
|
||||
if(CMAKE_C_COMPILER)
|
||||
set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\"")
|
||||
set_conan_compiler_if_appleclang(C cc _conan_c_compiler)
|
||||
list(APPEND _conan_compilers_list ${_conan_c_compiler})
|
||||
else()
|
||||
message(WARNING "CMake-Conan: The C compiler is not defined. "
|
||||
"Please define CMAKE_C_COMPILER or enable the C language.")
|
||||
endif()
|
||||
if(CMAKE_CXX_COMPILER)
|
||||
set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"")
|
||||
set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler)
|
||||
list(APPEND _conan_compilers_list ${_conan_cpp_compiler})
|
||||
else()
|
||||
message(WARNING "CMake-Conan: The C++ compiler is not defined. "
|
||||
"Please define CMAKE_CXX_COMPILER or enable the C++ language.")
|
||||
endif()
|
||||
if(CMAKE_RC_COMPILER)
|
||||
set(_conan_rc_compiler "\"rc\":\"${CMAKE_RC_COMPILER}\"")
|
||||
list(APPEND _conan_compilers_list ${_conan_rc_compiler})
|
||||
# Not necessary to warn if RC not defined
|
||||
endif()
|
||||
if(NOT "x${_conan_compilers_list}" STREQUAL "x")
|
||||
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}")
|
||||
string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n")
|
||||
endif()
|
||||
endif()
|
||||
unset(_conan_c_compiler)
|
||||
unset(_conan_cpp_compiler)
|
||||
unset(_conan_rc_compiler)
|
||||
unset(_conan_compilers_list)
|
||||
endmacro()
|
||||
|
||||
|
||||
function(detect_host_profile output_file)
|
||||
detect_os(os os_api_level os_sdk os_subsystem os_version)
|
||||
detect_arch(arch)
|
||||
detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type)
|
||||
detect_cxx_standard(${compiler} compiler_cppstd)
|
||||
detect_lib_cxx(compiler_libcxx)
|
||||
detect_build_type(build_type)
|
||||
|
||||
set(profile "")
|
||||
string(APPEND profile "[settings]\n")
|
||||
if(arch)
|
||||
string(APPEND profile arch=${arch} "\n")
|
||||
endif()
|
||||
if(os)
|
||||
string(APPEND profile os=${os} "\n")
|
||||
endif()
|
||||
if(os_api_level)
|
||||
string(APPEND profile os.api_level=${os_api_level} "\n")
|
||||
endif()
|
||||
if(os_version)
|
||||
string(APPEND profile os.version=${os_version} "\n")
|
||||
endif()
|
||||
if(os_sdk)
|
||||
string(APPEND profile os.sdk=${os_sdk} "\n")
|
||||
endif()
|
||||
if(os_subsystem)
|
||||
string(APPEND profile os.subsystem=${os_subsystem} "\n")
|
||||
endif()
|
||||
if(compiler)
|
||||
string(APPEND profile compiler=${compiler} "\n")
|
||||
endif()
|
||||
if(compiler_version)
|
||||
string(APPEND profile compiler.version=${compiler_version} "\n")
|
||||
endif()
|
||||
if(compiler_runtime)
|
||||
string(APPEND profile compiler.runtime=${compiler_runtime} "\n")
|
||||
endif()
|
||||
if(compiler_runtime_type)
|
||||
string(APPEND profile compiler.runtime_type=${compiler_runtime_type} "\n")
|
||||
endif()
|
||||
if(compiler_cppstd)
|
||||
string(APPEND profile compiler.cppstd=${compiler_cppstd} "\n")
|
||||
endif()
|
||||
if(compiler_libcxx)
|
||||
string(APPEND profile compiler.libcxx=${compiler_libcxx} "\n")
|
||||
endif()
|
||||
if(build_type)
|
||||
string(APPEND profile "build_type=${build_type}\n")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED output_file)
|
||||
set(file_name "${CMAKE_BINARY_DIR}/profile")
|
||||
else()
|
||||
set(file_name ${output_file})
|
||||
endif()
|
||||
|
||||
string(APPEND profile "[conf]\n")
|
||||
string(APPEND profile "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n")
|
||||
|
||||
# propagate compilers via profile
|
||||
append_compiler_executables_configuration()
|
||||
|
||||
if(os STREQUAL "Android")
|
||||
string(APPEND profile "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n")
|
||||
endif()
|
||||
|
||||
message(STATUS "CMake-Conan: Creating profile ${file_name}")
|
||||
file(WRITE ${file_name} ${profile})
|
||||
message(STATUS "CMake-Conan: Profile: \n${profile}")
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_profile_detect_default)
|
||||
message(STATUS "CMake-Conan: Checking if a default profile exists")
|
||||
execute_process(COMMAND ${CONAN_COMMAND} profile path default
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
ECHO_OUTPUT_VARIABLE
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
if(NOT ${return_code} EQUAL "0")
|
||||
message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.")
|
||||
execute_process(COMMAND ${CONAN_COMMAND} profile detect
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
ECHO_OUTPUT_VARIABLE
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_install)
|
||||
set(conan_output_folder ${CMAKE_BINARY_DIR}/conan)
|
||||
# Invoke "conan install" with the provided arguments
|
||||
set(conan_args -of=${conan_output_folder})
|
||||
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}")
|
||||
|
||||
|
||||
# In case there was not a valid cmake executable in the PATH, we inject the
|
||||
# same we used to invoke the provider to the PATH
|
||||
if(DEFINED PATH_TO_CMAKE_BIN)
|
||||
set(old_path $ENV{PATH})
|
||||
set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}")
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN} --format=json
|
||||
RESULT_VARIABLE return_code
|
||||
OUTPUT_VARIABLE conan_stdout
|
||||
ERROR_VARIABLE conan_stderr
|
||||
ECHO_ERROR_VARIABLE # show the text output regardless
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
if(DEFINED PATH_TO_CMAKE_BIN)
|
||||
set(ENV{PATH} "${old_path}")
|
||||
endif()
|
||||
|
||||
if(NOT "${return_code}" STREQUAL "0")
|
||||
message(FATAL_ERROR "Conan install failed='${return_code}'")
|
||||
endif()
|
||||
|
||||
# the files are generated in a folder that depends on the layout used, if
|
||||
# one is specified, but we don't know a priori where this is.
|
||||
# TODO: this can be made more robust if Conan can provide this in the json output
|
||||
string(JSON conan_generators_folder GET "${conan_stdout}" graph nodes 0 generators_folder)
|
||||
cmake_path(CONVERT ${conan_generators_folder} TO_CMAKE_PATH_LIST conan_generators_folder)
|
||||
|
||||
message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${conan_generators_folder}")
|
||||
set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${conan_generators_folder}")
|
||||
# reconfigure on conanfile changes
|
||||
string(JSON conanfile GET "${conan_stdout}" graph nodes 0 label)
|
||||
message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${conanfile}")
|
||||
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${conanfile}")
|
||||
# success
|
||||
set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE)
|
||||
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_get_version conan_command conan_current_version)
|
||||
execute_process(
|
||||
COMMAND ${conan_command} --version
|
||||
OUTPUT_VARIABLE conan_output
|
||||
RESULT_VARIABLE conan_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(conan_result)
|
||||
message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan")
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output})
|
||||
set(${conan_current_version} ${conan_version} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(conan_version_check)
|
||||
set(options )
|
||||
set(one_value_args MINIMUM CURRENT)
|
||||
set(multi_value_args )
|
||||
cmake_parse_arguments(conan_version_check
|
||||
"${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
|
||||
|
||||
if(NOT conan_version_check_MINIMUM)
|
||||
message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!")
|
||||
endif()
|
||||
if(NOT conan_version_check_CURRENT)
|
||||
message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!")
|
||||
endif()
|
||||
|
||||
if(conan_version_check_CURRENT VERSION_LESS conan_version_check_MINIMUM)
|
||||
message(FATAL_ERROR "CMake-Conan: Conan version must be ${conan_version_check_MINIMUM} or later")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(construct_profile_argument argument_variable profile_list)
|
||||
set(${argument_variable} "")
|
||||
if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE")
|
||||
set(_arg_flag "--profile:host=")
|
||||
elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE")
|
||||
set(_arg_flag "--profile:build=")
|
||||
endif()
|
||||
|
||||
set(_profile_list "${${profile_list}}")
|
||||
list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile")
|
||||
list(TRANSFORM _profile_list PREPEND ${_arg_flag})
|
||||
set(${argument_variable} ${_profile_list})
|
||||
|
||||
unset(_arg_flag)
|
||||
unset(_profile_list)
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(conan_provide_dependency method package_name)
|
||||
set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE)
|
||||
get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS)
|
||||
if(NOT _conan_install_success)
|
||||
find_program(CONAN_COMMAND "conan" REQUIRED)
|
||||
conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION)
|
||||
conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION})
|
||||
message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan")
|
||||
if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE)
|
||||
conan_profile_detect_default()
|
||||
endif()
|
||||
if("auto-cmake" IN_LIST CONAN_HOST_PROFILE)
|
||||
detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile)
|
||||
endif()
|
||||
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
|
||||
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
|
||||
if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py")
|
||||
file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile)
|
||||
if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*")
|
||||
message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile")
|
||||
endif()
|
||||
elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt")
|
||||
file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile)
|
||||
if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*")
|
||||
message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
|
||||
if(DEFINED CONAN_INSTALL_BUILD_CONFIGURATIONS)
|
||||
# Configurations are specified by the project or user
|
||||
set(_build_configs "${CONAN_INSTALL_BUILD_CONFIGURATIONS}")
|
||||
list(LENGTH _build_configs _build_configs_length)
|
||||
if(NOT _multiconfig_generator AND _build_configs_length GREATER 1)
|
||||
message(FATAL_ERROR "cmake-conan: when using a single-config CMake generator, "
|
||||
"please only specify a single configuration in CONAN_INSTALL_BUILD_CONFIGURATIONS")
|
||||
endif()
|
||||
unset(_build_configs_length)
|
||||
else()
|
||||
# No configuration overrides, provide sensible defaults
|
||||
if(_multiconfig_generator)
|
||||
set(_build_configs Release Debug)
|
||||
else()
|
||||
set(_build_configs ${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
list(JOIN _build_configs ", " _build_configs_msg)
|
||||
message(STATUS "CMake-Conan: Installing configuration(s): ${_build_configs_msg}")
|
||||
foreach(_build_config IN LISTS _build_configs)
|
||||
set(_self_build_config "")
|
||||
if(NOT _multiconfig_generator AND NOT _build_config STREQUAL "${CMAKE_BUILD_TYPE}")
|
||||
set(_self_build_config -s &:build_type=${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=${_build_config} ${_self_build_config} ${CONAN_INSTALL_ARGS})
|
||||
endforeach()
|
||||
|
||||
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
|
||||
if(EXISTS "${_conan_generators_folder}/conan_cmakedeps_paths.cmake")
|
||||
message(STATUS "CMake-Conan: Loading conan_cmakedeps_paths.cmake file")
|
||||
include(${_conan_generators_folder}/conan_cmakedeps_paths.cmake)
|
||||
endif()
|
||||
|
||||
unset(_self_build_config)
|
||||
unset(_multiconfig_generator)
|
||||
unset(_build_configs)
|
||||
unset(_build_configs_msg)
|
||||
unset(_host_profile_flags)
|
||||
unset(_build_profile_flags)
|
||||
unset(_conan_install_success)
|
||||
else()
|
||||
message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran")
|
||||
unset(_conan_install_success)
|
||||
endif()
|
||||
|
||||
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
|
||||
|
||||
# Ensure that we consider Conan-provided packages ahead of any other,
|
||||
# irrespective of other settings that modify the search order or search paths
|
||||
# This follows the guidelines from the find_package documentation
|
||||
# (https://cmake.org/cmake/help/latest/command/find_package.html):
|
||||
# find_package (<PackageName> PATHS paths... NO_DEFAULT_PATH)
|
||||
# find_package (<PackageName>)
|
||||
|
||||
# Filter out `REQUIRED` from the argument list, as the first call may fail
|
||||
set(_find_args_${package_name} "${ARGN}")
|
||||
list(REMOVE_ITEM _find_args_${package_name} "REQUIRED")
|
||||
if(NOT "MODULE" IN_LIST _find_args_${package_name})
|
||||
find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
unset(_find_args_${package_name})
|
||||
endif()
|
||||
|
||||
# Invoke find_package a second time - if the first call succeeded,
|
||||
# this will simply reuse the result. If not, fall back to CMake default search
|
||||
# behaviour, also allowing modules to be searched.
|
||||
if(NOT ${package_name}_FOUND)
|
||||
list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index)
|
||||
if(_index EQUAL -1)
|
||||
list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}")
|
||||
endif()
|
||||
unset(_index)
|
||||
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
|
||||
list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
cmake_language(
|
||||
SET_DEPENDENCY_PROVIDER conan_provide_dependency
|
||||
SUPPORTED_METHODS FIND_PACKAGE
|
||||
)
|
||||
|
||||
|
||||
macro(conan_provide_dependency_check)
|
||||
set(_conan_provide_dependency_invoked FALSE)
|
||||
get_property(_conan_provide_dependency_invoked GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED)
|
||||
if(NOT _conan_provide_dependency_invoked)
|
||||
message(WARNING "Conan is correctly configured as dependency provider, "
|
||||
"but Conan has not been invoked. Please add at least one "
|
||||
"call to `find_package()`.")
|
||||
if(DEFINED CONAN_COMMAND)
|
||||
# supress warning in case `CONAN_COMMAND` was specified but unused.
|
||||
set(_conan_command ${CONAN_COMMAND})
|
||||
unset(_conan_command)
|
||||
endif()
|
||||
endif()
|
||||
unset(_conan_provide_dependency_invoked)
|
||||
endmacro()
|
||||
|
||||
|
||||
# Add a deferred call at the end of processing the top-level directory
|
||||
# to check if the dependency provider was invoked at all.
|
||||
cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check)
|
||||
|
||||
# Configurable variables for Conan profiles
|
||||
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
|
||||
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")
|
||||
set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install")
|
||||
|
||||
find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
|
||||
if(NOT _cmake_program)
|
||||
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
|
||||
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
|
||||
endif()
|
||||
|
||||
cmake_policy(POP)
|
||||
@@ -0,0 +1,42 @@
|
||||
from conan import ConanFile
|
||||
|
||||
class AmneziaVPN(ConanFile):
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
generators = "CMakeConfigDeps"
|
||||
|
||||
options = {
|
||||
"macos_ne": [True, False]
|
||||
}
|
||||
default_options = {
|
||||
"macos_ne": False
|
||||
}
|
||||
|
||||
def requirements(self):
|
||||
os = str(self.settings.os)
|
||||
|
||||
has_ne = os == "iOS" or (os == "Macos" and self.options.macos_ne)
|
||||
has_service = os == "Windows" or os == "Linux" or (os == "Macos" and not has_ne)
|
||||
|
||||
if has_service:
|
||||
if os == "Windows":
|
||||
self.requires("awg-windows/1.0.0")
|
||||
else:
|
||||
self.requires("awg-go/0.2.16")
|
||||
|
||||
self.requires("amnezia-xray-bindings/1.1.0")
|
||||
self.requires("tun2socks/2.6.0")
|
||||
self.requires("openvpn/2.7.0")
|
||||
self.requires("v2ray-rules-dat/[*]")
|
||||
|
||||
if has_ne:
|
||||
self.requires("awg-apple/2.0.1")
|
||||
self.requires("hev-socks5-tunnel/2.14.4", options={"as_framework": True})
|
||||
self.requires("openvpnadapter/1.0.0")
|
||||
|
||||
if os == "Android":
|
||||
self.requires("amnezia-libxray/1.0.0")
|
||||
self.requires("awg-android/1.1.7")
|
||||
self.requires("openvpn-pt-android/1.0.0")
|
||||
|
||||
self.requires("libssh/0.11.3@amnezia")
|
||||
self.requires("openssl/3.5.5")
|
||||
@@ -14,6 +14,8 @@ sc stop AmneziaVPN-service
|
||||
sc delete AmneziaVPN-service
|
||||
sc stop AmneziaWGTunnel$AmneziaVPN
|
||||
sc delete AmneziaWGTunnel$AmneziaVPN
|
||||
sc stop AmneziaVPNSplitTunnel
|
||||
sc delete AmneziaVPNSplitTunnel
|
||||
taskkill /IM "AmneziaVPN-service.exe" /F
|
||||
taskkill /IM "AmneziaVPN.exe" /F
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ sc stop AmneziaVPN-service
|
||||
sc delete AmneziaVPN-service
|
||||
sc stop AmneziaWGTunnel$AmneziaVPN
|
||||
sc delete AmneziaWGTunnel$AmneziaVPN
|
||||
sc stop AmneziaVPNSplitTunnel
|
||||
sc delete AmneziaVPNSplitTunnel
|
||||
taskkill /IM "AmneziaVPN-service.exe" /F
|
||||
taskkill /IM "AmneziaVPN.exe" /F
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.files import get, copy
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
|
||||
import os
|
||||
import stat
|
||||
|
||||
class AmneziaLibxray(ConanFile):
|
||||
name = "amnezia-libxray"
|
||||
version = "1.0.0"
|
||||
|
||||
settings = "os", "arch"
|
||||
options = {"page_16k": [True, False]}
|
||||
default_options = {"page_16k": True}
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self, build_folder=".")
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("go/1.26.0")
|
||||
|
||||
def validate(self):
|
||||
if self.settings.os != "Android":
|
||||
raise ConanInvalidConfiguration(f"{self.name} v{self.version} does not support {self.settings.os}")
|
||||
|
||||
def source(self):
|
||||
get(self, "https://github.com/amnezia-vpn/amnezia-libxray/archive/refs/tags/v1.0.0.zip",
|
||||
sha256="0c50c5acd5063a9fc3cfbb5b3e11481d30cfa3762b3cb1d72130248ff498e9df", strip_root=True
|
||||
)
|
||||
|
||||
def _patch_sources(self):
|
||||
build_path = os.path.join(self.build_folder, "build.sh")
|
||||
build_stat = os.stat(build_path)
|
||||
os.chmod(build_path, build_stat.st_mode | stat.S_IEXEC)
|
||||
|
||||
def build(self):
|
||||
self._patch_sources()
|
||||
cgo_ldflags = 'CGO_LDFLAGS="-Wl,-z,max-page-size=16384" ' if self.options.page_16k else ""
|
||||
self.run(f'{cgo_ldflags}./build.sh android')
|
||||
|
||||
def package(self):
|
||||
copy(self, "libxray.aar", src=self.build_folder, dst=os.path.join(self.package_folder, "aar"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_extra_variables", {
|
||||
"AMNEZIA_LIBXRAY_PATH": os.path.join(self.package_folder, "aar", "libxray.aar"),
|
||||
})
|
||||
@@ -0,0 +1,90 @@
|
||||
# conanfile.py
|
||||
from conan import ConanFile
|
||||
from conan.tools.files import get, copy, collect_libs, chdir
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.gnu import Autotools, AutotoolsToolchain
|
||||
from conan.tools.env import Environment
|
||||
|
||||
import os
|
||||
|
||||
class AmneziaXrayBindings(ConanFile):
|
||||
name = "amnezia-xray-bindings"
|
||||
version = "1.1.0"
|
||||
|
||||
settings = "os", "arch"
|
||||
|
||||
@property
|
||||
def _goos(self):
|
||||
return {
|
||||
"Linux": "linux",
|
||||
"iOS": "ios",
|
||||
"Macos": "darwin",
|
||||
"Windows": "windows"
|
||||
}.get(str(self.settings.os))
|
||||
|
||||
@property
|
||||
def _goarch(self):
|
||||
return {
|
||||
"x86": "386",
|
||||
"x86_64": "amd64",
|
||||
"armv8": "arm64"
|
||||
}.get(str(self.settings.arch))
|
||||
|
||||
@property
|
||||
def _is_windows(self):
|
||||
return str(self.settings.os).startswith("Windows")
|
||||
|
||||
def validate(self):
|
||||
if not self._goos or not self._goarch:
|
||||
raise ConanInvalidConfiguration(
|
||||
f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}"
|
||||
)
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self)
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("go/1.26.0")
|
||||
|
||||
def source(self):
|
||||
get(self, "https://github.com/amnezia-vpn/amnezia-xray-bindings/archive/v1.1.0.zip",
|
||||
sha256="6ea768ec7002cedd422a39aea17704b888acaf794432aa5937cfc92fb6d80eb5", strip_root=True)
|
||||
|
||||
def generate(self):
|
||||
tc = AutotoolsToolchain(self)
|
||||
env = Environment()
|
||||
env.define("ARCH", self._goarch)
|
||||
env.define("GOARCH", self._goarch)
|
||||
env.define("GOOS", self._goos)
|
||||
env.define("CGO_LDFLAGS", tc.ldflags)
|
||||
env.define("CGO_CFLAGS", tc.cflags)
|
||||
if self._is_windows:
|
||||
env.define("OS", "windows")
|
||||
tc.generate(env)
|
||||
|
||||
def build(self):
|
||||
with chdir(self, self.source_folder):
|
||||
autotools = Autotools(self)
|
||||
autotools.make()
|
||||
|
||||
def _rename_libs(self):
|
||||
# workaround of bad naming strategy in amnezia-xray-bindings
|
||||
# TODO: change it and kick out the code below
|
||||
lib_dir = os.path.join(self.package_folder, "lib")
|
||||
for fname in os.listdir(lib_dir):
|
||||
if not fname.startswith("lib"):
|
||||
src = os.path.join(lib_dir, fname)
|
||||
dst = os.path.join(lib_dir, "lib" + fname)
|
||||
os.rename(src, dst)
|
||||
|
||||
def package(self):
|
||||
copy(self, "*.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include"))
|
||||
copy(self, "*.a", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.dll", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"))
|
||||
self._rename_libs()
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_target_name", "amnezia::xray-bindings")
|
||||
self.cpp_info.libs = collect_libs(self)
|
||||
@@ -0,0 +1,131 @@
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
|
||||
from conan import ConanFile
|
||||
from conan.tools.files import copy
|
||||
from conan.tools.scm import Git
|
||||
from conan.errors import ConanInvalidConfiguration, ConanException
|
||||
|
||||
|
||||
class AndroidOpenSSL(ConanFile):
|
||||
name = "android-openssl"
|
||||
version = "3.5.5"
|
||||
settings = "os", "arch"
|
||||
options = {"page_16k": [True, False]}
|
||||
default_options = {"page_16k": True}
|
||||
|
||||
# Conan arch → OpenSSL Configure target
|
||||
_arch_map = {
|
||||
"armv8": "android-arm64",
|
||||
"armv7": "android-arm",
|
||||
"x86_64": "android-x86_64",
|
||||
"x86": "android-x86",
|
||||
}
|
||||
|
||||
def validate(self):
|
||||
if self.settings.os != "Android":
|
||||
raise ConanInvalidConfiguration(f"{self.name} only supports Android")
|
||||
if str(self.settings.arch) not in self._arch_map:
|
||||
raise ConanInvalidConfiguration(f"Unsupported arch: {self.settings.arch}")
|
||||
|
||||
def source(self):
|
||||
git = Git(self)
|
||||
git.clone(
|
||||
url="https://github.com/openssl/openssl.git",
|
||||
target=".",
|
||||
args=["--branch", f"openssl-{self.version}", "--depth", "1"]
|
||||
)
|
||||
|
||||
def _ndk(self):
|
||||
ndk = self.conf.get("tools.android:ndk_path", check_type=str) or \
|
||||
os.environ.get("ANDROID_NDK_ROOT", "")
|
||||
if not ndk:
|
||||
raise ConanException(
|
||||
"Android NDK not found. Set tools.android:ndk_path conf or ANDROID_NDK_ROOT env."
|
||||
)
|
||||
return ndk
|
||||
|
||||
def _toolchain_bin(self):
|
||||
host = "linux-x86_64" if platform.system() == "Linux" else "darwin-x86_64"
|
||||
return os.path.join(self._ndk(), "toolchains", "llvm", "prebuilt", host, "bin")
|
||||
|
||||
def _patch_makefile(self, makefile_path, page_16k=False):
|
||||
"""Rename libcrypto.so → libcrypto_3.so and libssl.so → libssl_3.so
|
||||
throughout the generated Makefile so the built files already carry the
|
||||
correct names and sonames — no patchelf required.
|
||||
Optionally append the 16KB page-size linker flag to LDFLAGS."""
|
||||
with open(makefile_path, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Replace every standalone libcrypto.so / libssl.so reference.
|
||||
# \b word-boundary keeps us from matching libcrypto.so.3 style names.
|
||||
content = re.sub(r"\blibcrypto\.so\b", "libcrypto_3.so", content)
|
||||
content = re.sub(r"\blibssl\.so\b", "libssl_3.so", content)
|
||||
|
||||
if page_16k:
|
||||
page_flag = "-Wl,-z,max-page-size=16384"
|
||||
content = re.sub(
|
||||
r"^(LDFLAGS\s*=)(.*?)$",
|
||||
lambda m: m.group(0) + " " + page_flag if page_flag not in m.group(0) else m.group(0),
|
||||
content,
|
||||
flags=re.MULTILINE,
|
||||
)
|
||||
|
||||
with open(makefile_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
def build(self):
|
||||
ndk = self._ndk()
|
||||
toolchain_bin = self._toolchain_bin()
|
||||
target = self._arch_map[str(self.settings.arch)]
|
||||
api_level = str(self.settings.os.api_level)
|
||||
jobs = os.cpu_count() or 4
|
||||
|
||||
env_prefix = f'PATH="{toolchain_bin}:$PATH" ANDROID_NDK_ROOT="{ndk}"'
|
||||
|
||||
configure_cmd = (
|
||||
f"./Configure {target} shared no-tests"
|
||||
f" -D__ANDROID_API__={api_level}"
|
||||
)
|
||||
|
||||
self.run(f"{env_prefix} {configure_cmd}", cwd=self.source_folder)
|
||||
|
||||
self._patch_makefile(
|
||||
os.path.join(self.source_folder, "Makefile"),
|
||||
page_16k=bool(self.options.page_16k),
|
||||
)
|
||||
|
||||
self.run(
|
||||
f"{env_prefix} make -j{jobs} SHLIB_VERSION_NUMBER= build_libs",
|
||||
cwd=self.source_folder
|
||||
)
|
||||
|
||||
def package(self):
|
||||
lib_dst = os.path.join(self.package_folder, "lib")
|
||||
os.makedirs(lib_dst, exist_ok=True)
|
||||
|
||||
copy(self, "libcrypto_3.so", src=self.source_folder, dst=lib_dst, keep_path=False)
|
||||
copy(self, "libssl_3.so", src=self.source_folder, dst=lib_dst, keep_path=False)
|
||||
|
||||
# Static libs (still named without suffix)
|
||||
copy(self, "libcrypto.a", src=self.source_folder, dst=lib_dst, keep_path=False)
|
||||
copy(self, "libssl.a", src=self.source_folder, dst=lib_dst, keep_path=False)
|
||||
|
||||
# Headers
|
||||
copy(self, "include/openssl/*.h", src=self.source_folder, dst=self.package_folder)
|
||||
|
||||
def package_info(self):
|
||||
# Expose the same CMake targets as the upstream openssl package so
|
||||
# consumers (libssh, main app) need no changes to their target_link_libraries.
|
||||
self.cpp_info.components["crypto"].set_property("cmake_target_name", "OpenSSL::Crypto")
|
||||
self.cpp_info.components["crypto"].libs = ["crypto_3"]
|
||||
self.cpp_info.components["crypto"].includedirs = ["include"]
|
||||
self.cpp_info.components["crypto"].libdirs = ["lib"]
|
||||
|
||||
self.cpp_info.components["ssl"].set_property("cmake_target_name", "OpenSSL::SSL")
|
||||
self.cpp_info.components["ssl"].libs = ["ssl_3"]
|
||||
self.cpp_info.components["ssl"].includedirs = []
|
||||
self.cpp_info.components["ssl"].libdirs = ["lib"]
|
||||
self.cpp_info.components["ssl"].requires = ["crypto"]
|
||||
@@ -0,0 +1,94 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain
|
||||
from conan.tools.env import VirtualBuildEnv
|
||||
from conan.tools.files import copy, replace_in_file
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.scm import Git
|
||||
|
||||
import os
|
||||
import platform
|
||||
|
||||
class AwgAndroid(ConanFile):
|
||||
name = "awg-android"
|
||||
version = "1.1.7"
|
||||
settings = "os", "arch", "build_type", "compiler"
|
||||
package_type = "shared-library"
|
||||
options = {"page_16k": [True, False]}
|
||||
default_options = {"page_16k": True}
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("cmake/[>=3.4.1 <4]")
|
||||
|
||||
def validate(self):
|
||||
if self.settings.os != "Android":
|
||||
raise ConanInvalidConfiguration(f"{self.name} v{self.version} does not support {self.settings.os}")
|
||||
|
||||
def source(self):
|
||||
git = Git(self)
|
||||
git.clone(
|
||||
url="https://github.com/amnezia-vpn/amneziawg-android.git",
|
||||
target=".",
|
||||
args=["--recurse-submodules", "--branch", f"v{self.version}"]
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.variables["GRADLE_USER_HOME"] = os.path.join(self.build_folder, "gradle_user_home")
|
||||
tc.variables["CMAKE_LIBRARY_OUTPUT_DIRECTORY"] = os.path.join(self.build_folder, "out")
|
||||
if self.options.page_16k:
|
||||
# Use cache_variables to override NDK toolchain defaults (extra_ldflags sets _INIT
|
||||
# variants which the NDK toolchain can override). CMAKE_SHARED_LINKER_FLAGS is passed
|
||||
# directly to the Go Makefile as LDFLAGS, which flows into CGO_LDFLAGS.
|
||||
page_flag = "-Wl,-z,max-page-size=16384"
|
||||
tc.cache_variables["CMAKE_EXE_LINKER_FLAGS"] = page_flag
|
||||
tc.cache_variables["CMAKE_SHARED_LINKER_FLAGS"] = page_flag
|
||||
tc.generate()
|
||||
|
||||
vbe = VirtualBuildEnv(self)
|
||||
vbe.generate()
|
||||
|
||||
def _patch_sources(self):
|
||||
if platform.system() == 'Darwin':
|
||||
replace_in_file(self,
|
||||
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
|
||||
'flock "$@.lock" -c \' \\\n',
|
||||
"",
|
||||
)
|
||||
replace_in_file(self,
|
||||
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
|
||||
'mv "$@.tmp" "$@"\'',
|
||||
'mv "$@.tmp" "$@"',
|
||||
)
|
||||
replace_in_file(self,
|
||||
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
|
||||
'touch "$@"\'',
|
||||
'touch "$@"',
|
||||
)
|
||||
replace_in_file(self,
|
||||
os.path.join(self.source_folder, "tunnel", "tools", "libwg-go", "Makefile"),
|
||||
'sha256sum -c',
|
||||
'shasum -a 256 -c'
|
||||
)
|
||||
|
||||
def build(self):
|
||||
self._patch_sources()
|
||||
cmake = CMake(self)
|
||||
cmake.configure(build_script_folder=os.path.join(self.source_folder, "tunnel", "tools"))
|
||||
cmake.build(target=["libwg-go.so", "libwg.so", "libwg-quick.so"])
|
||||
|
||||
def package(self):
|
||||
copy(self, "libwg-go.h", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "include"))
|
||||
copy(self, "libwg-go.so", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "libwg.so", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "bin"))
|
||||
copy(self, "libwg-quick.so", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "bin"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_target_name", "amnezia::awg-android")
|
||||
self.cpp_info.libs = [ "wg-go" ]
|
||||
self.cpp_info.set_property("cmake_extra_variables", {
|
||||
"AMNEZIA_ANDROID_LIBWG_PATH": os.path.join(self.package_folder, "bin", "libwg.so"),
|
||||
"AMNEZIA_ANDROID_LIBWG_QUICK_PATH": os.path.join(self.package_folder, "bin", "libwg-quick.so"),
|
||||
})
|
||||
@@ -0,0 +1,68 @@
|
||||
from conan import ConanFile
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.tools.files import get, copy, collect_libs, chdir
|
||||
from conan.tools.apple import is_apple_os
|
||||
from conan.tools.gnu import AutotoolsToolchain, Autotools
|
||||
|
||||
import os
|
||||
|
||||
class AwgApple(ConanFile):
|
||||
name = "awg-apple"
|
||||
version = "2.0.1"
|
||||
settings = "os", "arch"
|
||||
options = {
|
||||
"as_framework": [True, False]
|
||||
}
|
||||
default_options = {
|
||||
"as_framework": False
|
||||
}
|
||||
|
||||
@property
|
||||
def _goarch(self):
|
||||
arch_map = {
|
||||
"armv8": "arm64",
|
||||
"x86_64": "x86_64",
|
||||
}
|
||||
archs = str(self.settings.arch).split("|")
|
||||
return " ".join(arch_map.get(arch, arch) for arch in archs)
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("go/1.26.0")
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self, build_folder=os.path.join(self.folders.source, "Sources/WireGuardKitGo"))
|
||||
|
||||
def validate(self):
|
||||
if not is_apple_os(self):
|
||||
raise ConanInvalidConfiguration(
|
||||
f"{self.name} v{self.version} does not support {self.settings.os}"
|
||||
)
|
||||
|
||||
def source(self):
|
||||
get(self, f"https://github.com/amnezia-vpn/amneziawg-apple/archive/refs/tags/v{self.version}.zip",
|
||||
sha256="9fe4f8cfbb6a751558b54b7979db3a5ea46e49731912aae99f093e84a1433e97", strip_root=True
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
tc = AutotoolsToolchain(self)
|
||||
sdk = self.settings.get_safe("os.sdk", "macosx")
|
||||
tc.make_args = [
|
||||
f"ARCHS={self._goarch}",
|
||||
f"PLATFORM_NAME={sdk}"
|
||||
]
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
autotools = Autotools(self)
|
||||
autotools.make()
|
||||
autotools.make("version-header")
|
||||
|
||||
def package(self):
|
||||
copy(self, "wireguard.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include"))
|
||||
copy(self, "*.h", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "include"))
|
||||
copy(self, "*.a", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "lib"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_target_name", "amnezia::awg-apple")
|
||||
self.cpp_info.libs = collect_libs(self)
|
||||
@@ -0,0 +1,66 @@
|
||||
from conan import ConanFile
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.tools.files import get, copy
|
||||
from conan.tools.gnu import Autotools, AutotoolsToolchain
|
||||
from conan.tools.env import Environment
|
||||
|
||||
import os
|
||||
|
||||
class AwgGo(ConanFile):
|
||||
name = "awg-go"
|
||||
version = "0.2.16"
|
||||
package_type = "application"
|
||||
settings = "os", "arch"
|
||||
|
||||
@property
|
||||
def _goos(self):
|
||||
return {
|
||||
"Linux": "linux",
|
||||
"Macos": "darwin",
|
||||
"Windows": "windows"
|
||||
}.get(str(self.settings.os))
|
||||
|
||||
@property
|
||||
def _goarch(self):
|
||||
return {
|
||||
"x86": "386",
|
||||
"x86_64": "amd64",
|
||||
"armv8": "arm64"
|
||||
}.get(str(self.settings.arch))
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("go/1.26.0")
|
||||
|
||||
def validate(self):
|
||||
if not self._goos or not self._goarch:
|
||||
raise ConanInvalidConfiguration(
|
||||
f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}"
|
||||
)
|
||||
|
||||
def source(self):
|
||||
get(self, f"https://github.com/amnezia-vpn/amneziawg-go/archive/refs/tags/v{self.version}.zip",
|
||||
sha256="34da7d4189f215f3930de441548bc2a0c89d54d347a4fb85cb9c715fce6413aa", strip_root=True
|
||||
)
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self, build_folder=".")
|
||||
|
||||
def generate(self):
|
||||
tc = AutotoolsToolchain(self)
|
||||
env = Environment()
|
||||
env.define("GOOS", self._goos)
|
||||
env.define("GOARCH", self._goarch)
|
||||
tc.generate(env)
|
||||
|
||||
def build(self):
|
||||
at = Autotools(self)
|
||||
at.make()
|
||||
|
||||
def package(self):
|
||||
copy(self, "amneziawg-go", src=self.build_folder, dst=self.package_folder)
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.exe = True
|
||||
self.cpp_info.location = os.path.join(self.package_folder, "amneziawg-go")
|
||||
self.cpp_info.set_property("cmake_target_name", "amnezia::awg-go")
|
||||
@@ -0,0 +1,26 @@
|
||||
sources:
|
||||
"1.26.0":
|
||||
Macos:
|
||||
x86_64:
|
||||
url: "https://go.dev/dl/go1.26.0.darwin-amd64.tar.gz"
|
||||
sha256: "1ca28b7703cbea05a65b2a1d92d6b308610ef92f8824578a0874f2e60c9d5a22"
|
||||
armv8:
|
||||
url: "https://go.dev/dl/go1.26.0.darwin-arm64.tar.gz"
|
||||
sha256: "b1640525dfe68f066d56f200bef7bf4dce955a1a893bd061de6754c211431023"
|
||||
Linux:
|
||||
x86:
|
||||
url: "https://go.dev/dl/go1.26.0.linux-386.tar.gz"
|
||||
sha256: "35e2ec7a7ae6905a1fae5459197b70e3fcbc5e0a786a7d6ba8e49bcd38ad2e26"
|
||||
x86_64:
|
||||
url: "https://go.dev/dl/go1.26.0.linux-amd64.tar.gz"
|
||||
sha256: "aac1b08a0fb0c4e0a7c1555beb7b59180b05dfc5a3d62e40e9de90cd42f88235"
|
||||
armv8:
|
||||
url: "https://go.dev/dl/go1.26.0.linux-arm64.tar.gz"
|
||||
sha256: "bd03b743eb6eb4193ea3c3fd3956546bf0e3ca5b7076c8226334afe6b75704cd"
|
||||
Windows:
|
||||
x86:
|
||||
url: "https://go.dev/dl/go1.26.0.windows-386.zip"
|
||||
sha256: "50674f3d6a071fa1a4c1d76dc37fafa0330df87d84087a262fee020da5396b6b"
|
||||
x86_64:
|
||||
url: "https://go.dev/dl/go1.26.0.windows-amd64.zip"
|
||||
sha256: "9bbe0fc64236b2b51f6255c05c4232532b8ecc0e6d2e00950bd3021d8a4d07d4"
|
||||
@@ -0,0 +1,19 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.files import get, copy
|
||||
|
||||
import os
|
||||
|
||||
class Golang(ConanFile):
|
||||
name = "go"
|
||||
version = "1.26.0"
|
||||
|
||||
settings = "os", "arch"
|
||||
|
||||
def build(self):
|
||||
get(self, **self.conan_data["sources"][str(self.version)][str(self.settings.os)][str(self.settings.arch)])
|
||||
|
||||
def package(self):
|
||||
copy(self, "*", src=os.path.join(self.source_folder, "go"), dst=self.package_folder)
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.bindirs = ["bin"]
|
||||
@@ -0,0 +1,98 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.tools.scm import Git
|
||||
from conan.tools.files import copy, collect_libs
|
||||
from conan.internal.model.pkg_type import PackageType
|
||||
from conan.tools.gnu import AutotoolsToolchain, Autotools
|
||||
from conan.tools.apple import is_apple_os
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
|
||||
required_conan_version = ">=2.26"
|
||||
|
||||
|
||||
class HevSocks5Tunnel(ConanFile):
|
||||
name = "hev-socks5-tunnel"
|
||||
version = "2.14.4"
|
||||
settings = "os", "arch"
|
||||
options = {
|
||||
"shared": [True, False],
|
||||
"as_framework": [True, False],
|
||||
}
|
||||
default_options = {
|
||||
"shared": False,
|
||||
"as_framework": False
|
||||
}
|
||||
|
||||
def config_options(self):
|
||||
if not is_apple_os(self):
|
||||
del self.options.as_framework
|
||||
|
||||
def configure(self):
|
||||
if self.options.get_safe("as_framework"):
|
||||
self.options.shared = False
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self, build_folder=".")
|
||||
|
||||
def source(self):
|
||||
git = Git(self)
|
||||
git.clone(
|
||||
url="https://github.com/heiher/hev-socks5-tunnel.git",
|
||||
target=".",
|
||||
args=["--recurse-submodules", "--branch", self.version]
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
tc = AutotoolsToolchain(self)
|
||||
tc.generate()
|
||||
|
||||
def build(self):
|
||||
autotools = Autotools(self)
|
||||
autotools.make("shared" if self.options.shared else "static")
|
||||
|
||||
if self.options.get_safe("as_framework"):
|
||||
lib_path = os.path.join(self.build_folder, "bin", "libhev-socks5-tunnel.a")
|
||||
self.run(
|
||||
f"libtool -static -o {lib_path}"
|
||||
f" {lib_path}"
|
||||
f" {os.path.join(self.build_folder, "third-part", "lwip", "bin", "liblwip.a")}"
|
||||
f" {os.path.join(self.build_folder, "third-part", "yaml", "bin", "libyaml.a")}"
|
||||
f" {os.path.join(self.build_folder, "third-part", "hev-task-system", "bin", "libhev-task-system.a")}"
|
||||
)
|
||||
|
||||
include_dir = os.path.join(self.build_folder, "framework_include")
|
||||
copy(self, "hev-main.h", src=os.path.join(self.source_folder, "src"), dst=include_dir)
|
||||
copy(self, "module.modulemap", src=os.path.join(self.source_folder), dst=include_dir)
|
||||
|
||||
self.run('xcodebuild -create-xcframework'
|
||||
f' -library {lib_path}'
|
||||
f' -headers {include_dir}'
|
||||
f' -output {os.path.join(self.build_folder, "HevSocks5Tunnel.xcframework")}'
|
||||
)
|
||||
|
||||
def package(self):
|
||||
if self.options.get_safe("as_framework"):
|
||||
shutil.copytree(src=os.path.join(self.build_folder, "HevSocks5Tunnel.xcframework"),
|
||||
dst=os.path.join(self.package_folder, "HevSocks5Tunnel.xcframework"))
|
||||
else:
|
||||
copy(self, "hev-main.h", src=os.path.join(self.source_folder, "src"), dst=os.path.join(self.package_folder, "include"))
|
||||
copy(self, "*.a", src=os.path.join(self.build_folder, "bin"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.so", src=os.path.join(self.build_folder, "bin"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "lwip"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "lwip"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "yaml"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "yaml"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "hev-task-system"), dst=os.path.join(self.package_folder, "lib"))
|
||||
copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "hev-task-system"), dst=os.path.join(self.package_folder, "lib"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_target_name", "heiher::hev-socks5-tunnel")
|
||||
if self.options.get_safe("as_framework"):
|
||||
self.cpp_info.type = PackageType.STATIC
|
||||
self.cpp_info.package_framework = True
|
||||
self.cpp_info.location = os.path.join(self.package_folder, "HevSocks5Tunnel.xcframework")
|
||||
else:
|
||||
self.cpp_info.libraries = collect_libs(self)
|
||||
@@ -0,0 +1,142 @@
|
||||
from conan import ConanFile
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
|
||||
from conan.tools.files import copy, get, rmdir
|
||||
from conan.tools.microsoft import is_msvc_static_runtime, is_msvc
|
||||
from conan.tools.scm import Version
|
||||
import os
|
||||
|
||||
|
||||
required_conan_version = ">=2.21"
|
||||
|
||||
|
||||
class LibSSHRecipe(ConanFile):
|
||||
name = "libssh"
|
||||
version = "0.11.3"
|
||||
user = "amnezia"
|
||||
license = "LGPL-2.1"
|
||||
homepage = "https://www.libssh.org/"
|
||||
description = "multiplatform C library implementing the SSHv2 protocol on client and server side"
|
||||
topics = ("ssh", "shell", "ssh2", "connection")
|
||||
package_type = "library"
|
||||
settings = "os", "compiler", "build_type", "arch"
|
||||
options = {
|
||||
"shared": [True, False],
|
||||
"fPIC": [True, False],
|
||||
"with_zlib": [True, False],
|
||||
"crypto_backend": ["openssl", "gcrypt", "mbedtls"],
|
||||
"with_symbol_versioning": [True, False],
|
||||
"page_16k": [True, False],
|
||||
}
|
||||
default_options = {
|
||||
"shared": False,
|
||||
"fPIC": True,
|
||||
"with_zlib": True,
|
||||
"crypto_backend": "openssl",
|
||||
"with_symbol_versioning": True,
|
||||
"page_16k": True,
|
||||
}
|
||||
|
||||
def config_options(self):
|
||||
if self.settings.os == "Windows":
|
||||
del self.options.fPIC
|
||||
del self.options.with_symbol_versioning
|
||||
|
||||
def configure(self):
|
||||
if self.options.shared:
|
||||
self.options.rm_safe("fPIC")
|
||||
self.settings.rm_safe("compiler.libcxx")
|
||||
self.settings.rm_safe("compiler.cppstd")
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self, src_folder="src")
|
||||
|
||||
def requirements(self):
|
||||
if self.options.with_zlib:
|
||||
self.requires("zlib/[>=1.2.11 <2]")
|
||||
if self.options.crypto_backend == "openssl":
|
||||
if self.settings.os == "Android":
|
||||
self.requires("android-openssl/3.5.5")
|
||||
else:
|
||||
self.requires("openssl/[>=1.1 <4]")
|
||||
elif self.options.crypto_backend == "gcrypt":
|
||||
self.requires("libgcrypt/[>=1.8.4 <2]")
|
||||
elif self.options.crypto_backend == "mbedtls":
|
||||
self.requires("mbedtls/3.6.0")
|
||||
|
||||
def validate(self):
|
||||
if self.options.crypto_backend == "mbedtls" and not self.dependencies["mbedtls"].options.enable_threading:
|
||||
raise ConanInvalidConfiguration(f"{self.ref} requires '-o mbedtls/*:enable_threading=True' when using '-o libssh/*:crypto_backend=mbedtls'")
|
||||
|
||||
def source(self):
|
||||
get(self, "https://www.libssh.org/files/0.11/libssh-0.11.3.tar.xz",
|
||||
sha256="7d8a1361bb094ec3f511964e78a5a4dba689b5986e112afabe4f4d0d6c6125c3", strip_root=True
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.cache_variables["CLIENT_TESTING"] = False
|
||||
tc.cache_variables["SERVER_TESTING"] = False
|
||||
tc.cache_variables["WITH_EXAMPLES"] = False
|
||||
tc.cache_variables["WITH_GCRYPT"] = self.options.crypto_backend == "gcrypt"
|
||||
tc.cache_variables["WITH_GSSAPI"] = False
|
||||
tc.cache_variables["WITH_MBEDTLS"] = self.options.crypto_backend == "mbedtls"
|
||||
tc.cache_variables["WITH_NACL"] = False
|
||||
tc.cache_variables["WITH_SYMBOL_VERSIONING"] = self.options.get_safe("with_symbol_versioning", True)
|
||||
tc.variables["WITH_ZLIB"] = self.options.with_zlib
|
||||
if is_msvc(self):
|
||||
tc.cache_variables["USE_MSVC_RUNTIME_LIBRARY_DLL"] = not is_msvc_static_runtime(self)
|
||||
tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0077"] = "NEW"
|
||||
tc.cache_variables["CMAKE_TRY_COMPILE_CONFIGURATION"] = str(self.settings.build_type)
|
||||
if self.settings.os == "Android":
|
||||
if Version(self.settings.get_safe("os.api_level")) < 24:
|
||||
tc.cache_variables["HAVE_IFADDRS_H"] = False
|
||||
tc.cache_variables["HAVE_GLOB_H"] = False
|
||||
tc.preprocessor_definitions["S_IWRITE"] = "S_IRUSR"
|
||||
tc.preprocessor_definitions["S_IWRITE"] = "S_IWUSR"
|
||||
tc.preprocessor_definitions["S_IEXEC"] = "S_IXUSR"
|
||||
if self.options.page_16k:
|
||||
tc.cache_variables["CMAKE_SHARED_LINKER_FLAGS"] = "-Wl,-z,max-page-size=16384"
|
||||
tc.cache_variables["CMAKE_MODULE_LINKER_FLAGS"] = "-Wl,-z,max-page-size=16384"
|
||||
tc.generate()
|
||||
|
||||
deps = CMakeDeps(self)
|
||||
deps.set_property("libgcrypt", "cmake_file_name", "GCrypt")
|
||||
deps.set_property("libgcrypt", "cmake_additional_variables_prefixes", ["GCRYPT"])
|
||||
deps.set_property("libgcrypt", "cmake_extra_variables", {"GCRYPT_FOUND": "TRUE"})
|
||||
deps.set_property("mbedtls", "cmake_additional_variables_prefixes", ["MBEDTLS"])
|
||||
deps.set_property("mbedtls", "cmake_extra_variables", {"MBEDTLS_FOUND": "TRUE"})
|
||||
deps.generate()
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build()
|
||||
|
||||
def package(self):
|
||||
copy(self, pattern="COPYING", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
|
||||
cmake = CMake(self)
|
||||
cmake.install()
|
||||
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
|
||||
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.libs = ["ssh"]
|
||||
if not self.options.shared:
|
||||
self.cpp_info.defines.append("LIBSSH_STATIC=ON")
|
||||
if self.settings.os == "Windows":
|
||||
self.cpp_info.system_libs.extend(["ws2_32", "iphlpapi"])
|
||||
|
||||
self.cpp_info.set_property("cmake_file_name", "libssh")
|
||||
# target and alias names defined at:
|
||||
# ssh https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n351
|
||||
# ssh::ssh https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n371
|
||||
# ssh-static https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n413
|
||||
# ssh::static https://git.libssh.org/projects/libssh.git/tree/src/CMakeLists.txt?h=libssh-0.10.6#n428
|
||||
self.cpp_info.set_property("cmake_target_name", "ssh::ssh")
|
||||
self.cpp_info.set_property(
|
||||
"cmake_target_aliases",
|
||||
["ssh"] if self.options.shared else ["ssh", "ssh-static", "ssh::static"],
|
||||
)
|
||||
# pkg-config defined at https://git.libssh.org/projects/libssh.git/tree/CMakeLists.txt?h=libssh-0.10.6#n124
|
||||
self.cpp_info.set_property("pkg_config_name", "libssh")
|
||||
@@ -0,0 +1,67 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain
|
||||
from conan.tools.env import VirtualBuildEnv
|
||||
from conan.tools.files import copy
|
||||
from conan.tools.scm import Git
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
|
||||
import os
|
||||
|
||||
class OpenvpnPtAndroid(ConanFile):
|
||||
name = "openvpn-pt-android"
|
||||
version = "1.0.0"
|
||||
package_type = "shared-library"
|
||||
settings = "os", "arch", "build_type", "compiler"
|
||||
options = {"page_16k": [True, False]}
|
||||
default_options = {"page_16k": True}
|
||||
|
||||
def layout(self):
|
||||
cmake_layout(self)
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("swig/4.1.1")
|
||||
self.tool_requires("go/1.26.0")
|
||||
self.tool_requires("cmake/[>=3.4.1 <4]")
|
||||
|
||||
def validate(self):
|
||||
if self.settings.os != "Android":
|
||||
raise ConanInvalidConfiguration(f"{self.name} only supports Android, got {self.settings.os}")
|
||||
|
||||
def source(self):
|
||||
git = Git(self)
|
||||
git.clone(
|
||||
url="https://github.com/amnezia-vpn/openvpn-pt-android.git",
|
||||
target=".",
|
||||
args=["--recurse-submodules", "--branch", "update-ovpn3"]
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
tc = CMakeToolchain(self)
|
||||
tc.variables["ANDROID_PACKAGE_NAME"] = "org.amnezia.vpn"
|
||||
tc.variables["ANDROID_PLATFORM"] = 24
|
||||
if self.options.page_16k:
|
||||
page_flag = "-Wl,-z,max-page-size=16384"
|
||||
tc.cache_variables["CMAKE_SHARED_LINKER_FLAGS"] = page_flag
|
||||
tc.cache_variables["CMAKE_EXE_LINKER_FLAGS"] = page_flag
|
||||
tc.generate()
|
||||
|
||||
vbe = VirtualBuildEnv(self)
|
||||
if self.options.page_16k:
|
||||
vbe.environment().define("CGO_LDFLAGS", "-Wl,-z,max-page-size=16384")
|
||||
vbe.generate()
|
||||
|
||||
def build(self):
|
||||
cmake = CMake(self)
|
||||
cmake.configure()
|
||||
cmake.build(target=["ck_ovpn_plugin_go", "ovpn3", "ovpnutil", "rsapss"])
|
||||
|
||||
def package(self):
|
||||
copy(self, "*.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include"))
|
||||
copy(self, "*.so", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_target_name", "amnezia::openvpn-pt-android")
|
||||
self.cpp_info.libs = ["ovpn3", "ovpnutil", "rsapss"]
|
||||
self.cpp_info.set_property("cmake_extra_variables", {
|
||||
"OPENVPN_PT_ANDROID_LIBCK_OVPN_PLUGIN_PATH": os.path.join(self.package_folder, "lib", "libck-ovpn-plugin.so"),
|
||||
})
|
||||
@@ -0,0 +1,48 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.files import get, copy
|
||||
from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps
|
||||
from conan.tools.layout import basic_layout
|
||||
|
||||
import os
|
||||
|
||||
class Openvpn(ConanFile):
|
||||
name = "openvpn"
|
||||
version = "2.7.0"
|
||||
package_type = "application"
|
||||
settings = "os", "build_type", "arch"
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self)
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("libtool/2.4.7")
|
||||
self.tool_requires("automake/1.16.5")
|
||||
|
||||
def requirements(self):
|
||||
self.requires("openssl/[>=1.1.0]", visible=False)
|
||||
self.requires("lz4/[>=1.7.1]", visible=False)
|
||||
self.requires("lzo/2.10", visible=False)
|
||||
|
||||
def source(self):
|
||||
get(self, f"https://github.com/OpenVPN/openvpn/archive/refs/tags/v{self.version}.zip",
|
||||
sha256="1a65d8587f932c13d55b1f175ff2e1d61d795d9092788662e888054854d4ee3d", strip_root=True
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
tc = AutotoolsToolchain(self)
|
||||
tc.generate()
|
||||
deps = AutotoolsDeps(self)
|
||||
deps.generate()
|
||||
|
||||
def build(self):
|
||||
at = Autotools(self)
|
||||
at.autoreconf()
|
||||
at.configure()
|
||||
at.make()
|
||||
|
||||
def package(self):
|
||||
copy(self, "openvpn", src=os.path.join(self.build_folder, "src", "openvpn"), dst=self.package_folder)
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.exe = True
|
||||
self.cpp_info.location = os.path.join(self.package_folder, "openvpn")
|
||||
@@ -0,0 +1,72 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.tools.apple import is_apple_os
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.scm import Git
|
||||
from conan.internal.model.pkg_type import PackageType
|
||||
from conan.tools.files import chdir
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
class OpenVPNAdapter(ConanFile):
|
||||
name = "openvpnadapter"
|
||||
version = "1.0.0"
|
||||
settings = "os", "build_type"
|
||||
|
||||
@property
|
||||
def _sdk(self):
|
||||
return str(self.settings.get_safe("os.sdk", "macosx"))
|
||||
|
||||
@property
|
||||
def _platform(self):
|
||||
return {
|
||||
"macosx": "macOS",
|
||||
"iphoneos": "iOS",
|
||||
"iphonesimulator": "iOS Simulator"
|
||||
}.get(self._sdk)
|
||||
|
||||
@property
|
||||
def _configuration(self):
|
||||
return "Debug" if self.settings.get_safe("build_type") == "Debug" else "Release"
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self)
|
||||
|
||||
def validate(self):
|
||||
if not is_apple_os(self):
|
||||
raise ConanInvalidConfiguration(
|
||||
f"There is absolutely no point building Apple framework for {self.settings.os}"
|
||||
)
|
||||
|
||||
def source(self):
|
||||
git = Git(self)
|
||||
git.clone(
|
||||
url="https://github.com/amnezia-vpn/OpenVPNAdapter.git",
|
||||
target=".",
|
||||
args=["--recurse-submodules", "--branch", "master-amnezia"]
|
||||
)
|
||||
|
||||
def build(self):
|
||||
with chdir(self, self.source_folder):
|
||||
self.run("xcrun xcodebuild"
|
||||
" -project OpenVPNAdapter.xcodeproj"
|
||||
" -scheme OpenVPNAdapter"
|
||||
" -configuration Release"
|
||||
f" -destination 'generic/platform={self._platform}'"
|
||||
f" -sdk {self._sdk}"
|
||||
f' "CONFIGURATION_BUILD_DIR={self.build_folder}"'
|
||||
f' "BUILT_PRODUCTS_DIR={self.build_folder}"'
|
||||
" BUILD_LIBRARY_FOR_DISTRIBUTION=YES"
|
||||
" CODE_SIGNING_ALLOWED=NO"
|
||||
)
|
||||
|
||||
def package(self):
|
||||
shutil.copytree(os.path.join(self.build_folder, "OpenVPNAdapter.framework"),
|
||||
os.path.join(self.package_folder, "OpenVPNAdapter.framework"))
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_target_name", "amnezia::openvpnadapter")
|
||||
self.cpp_info.type = PackageType.STATIC
|
||||
self.cpp_info.package_framework = True
|
||||
self.cpp_info.location = os.path.join(self.package_folder, "OpenVPNAdapter.framework")
|
||||
@@ -0,0 +1,80 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.tools.files import get, copy, chdir
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
from conan.tools.gnu import Autotools, AutotoolsToolchain
|
||||
from conan.tools.env import Environment
|
||||
|
||||
import os
|
||||
|
||||
class Tun2Socks(ConanFile):
|
||||
name = "tun2socks"
|
||||
version = "2.6.0"
|
||||
package_type = "application"
|
||||
settings = "os", "arch"
|
||||
|
||||
@property
|
||||
def _goos(self):
|
||||
return {
|
||||
"Linux": "linux",
|
||||
"Macos": "darwin",
|
||||
"Windows": "windows"
|
||||
}.get(str(self.settings.os))
|
||||
|
||||
@property
|
||||
def _goarch(self):
|
||||
return {
|
||||
"x86": "386",
|
||||
"x86_64": "amd64",
|
||||
"armv8": "arm64"
|
||||
}.get(str(self.settings.arch))
|
||||
|
||||
@property
|
||||
def _is_windows(self):
|
||||
return str(self.settings.get_safe("os")).startswith("Windows")
|
||||
|
||||
@property
|
||||
def _ext(self):
|
||||
return ".exe" if self._is_windows else ""
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self)
|
||||
|
||||
def validate(self):
|
||||
if not self._goos or not self._goarch:
|
||||
raise ConanInvalidConfiguration(
|
||||
f"{self.name} v{self.version} does not support {self.settings.os} {self.settings.arch}"
|
||||
)
|
||||
|
||||
def build_requirements(self):
|
||||
self.tool_requires("go/1.26.0")
|
||||
|
||||
def source(self):
|
||||
get(self, f"https://github.com/xjasonlyu/tun2socks/archive/refs/tags/v{self.version}.zip",
|
||||
sha256="a7ef9cec1c30dfe9971af89a8aac767fd3d2a4df833e92b635642c2f0204c701", strip_root=True
|
||||
)
|
||||
|
||||
def generate(self):
|
||||
tc = AutotoolsToolchain(self)
|
||||
env = Environment()
|
||||
env.define("CGO_LDFLAGS", tc.ldflags)
|
||||
env.define("CGO_CFLAGS", tc.cflags)
|
||||
env.define("GOOS", self._goos)
|
||||
env.define("GOARCH", self._goarch)
|
||||
tc.generate(env)
|
||||
|
||||
def build(self):
|
||||
with chdir(self, self.source_folder):
|
||||
at = Autotools(self)
|
||||
at.make("tun2socks")
|
||||
|
||||
def package(self):
|
||||
copy(self, "tun2socks", src=self.build_folder, dst=self.package_folder)
|
||||
if self._is_windows:
|
||||
with chdir(self, self.package_folder):
|
||||
os.rename(src="tun2socks", dst="tun2socks.exe")
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.exe = True
|
||||
self.cpp_info.location = os.path.join(self.package_folder, f"tun2socks{self._ext}")
|
||||
self.cpp_info.set_property("cmake_target_name", "xjasonlyu::tun2socks")
|
||||
@@ -0,0 +1,29 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.layout import basic_layout
|
||||
from conan.tools.files import download, copy
|
||||
|
||||
import os
|
||||
|
||||
class V2rayRulesDat(ConanFile):
|
||||
name = "v2ray-rules-dat"
|
||||
version = "202603162227"
|
||||
|
||||
def layout(self):
|
||||
basic_layout(self, build_folder=".")
|
||||
|
||||
def source(self):
|
||||
# TODO(ygurov): build from source instead of plain copying
|
||||
download(self, filename="geoip.dat", url=f"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/{self.version}/geoip.dat",
|
||||
sha256="e48b925d985d7bf33cfee76f309241af0f1779699963b69363dec2c4740041d1")
|
||||
download(self, filename="geosite.dat", url=f"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/{self.version}/geosite.dat",
|
||||
sha256="a2f83e25b8be3f089cfdd9423fc7b6eda5a0d4060919917902711d65acac1e0c")
|
||||
|
||||
def package(self):
|
||||
copy(self, "*.dat", src=self.build_folder, dst=self.package_folder)
|
||||
|
||||
def package_info(self):
|
||||
self.cpp_info.set_property("cmake_target_name", "Loyalsoldier::v2ray-rules-dat")
|
||||
self.cpp_info.set_property("cmake_extra_variables", {
|
||||
"GEOSITE_DAT_PATH": os.path.join(self.package_folder, "geosite.dat"),
|
||||
"GEOIP_DAT_PATH": os.path.join(self.package_folder, "geoip.dat")
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
from conan import ConanFile
|
||||
|
||||
class PackageConan(ConanFile):
|
||||
name = "wintun"
|
||||
version = "1.0.0"
|
||||
@@ -9,62 +9,11 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
find_package(Qt6 REQUIRED COMPONENTS DBus Core Network Widgets RemoteObjects Core5Compat Concurrent)
|
||||
qt_standard_project_setup()
|
||||
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
|
||||
set(AMNEZIA_XRAY_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../../client/3rd-prebuilt/3rd-prebuilt/amnezia_xray")
|
||||
if(WIN32)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(AMNEZIA_XRAY_LIB_PATH "${AMNEZIA_XRAY_ROOT_DIR}/windows/x86_64/amnezia_xray.lib")
|
||||
set(AMNEZIA_XRAY_INCLUDE_DIR "${AMNEZIA_XRAY_ROOT_DIR}/windows/x86_64")
|
||||
else()
|
||||
set(AMNEZIA_XRAY_LIB_PATH "${AMNEZIA_XRAY_ROOT_DIR}/windows/x86/amnezia_xray.lib")
|
||||
set(AMNEZIA_XRAY_INCLUDE_DIR "${AMNEZIA_XRAY_ROOT_DIR}/windows/x86")
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
set(AMNEZIA_XRAY_LIB_PATH "${AMNEZIA_XRAY_ROOT_DIR}/macos/x86_64/amnezia_xray.a")
|
||||
set(AMNEZIA_XRAY_INCLUDE_DIR "${AMNEZIA_XRAY_ROOT_DIR}/macos/x86_64")
|
||||
elseif(LINUX)
|
||||
set(AMNEZIA_XRAY_LIB_PATH "${AMNEZIA_XRAY_ROOT_DIR}/linux/x86_64/amnezia_xray.a")
|
||||
set(AMNEZIA_XRAY_INCLUDE_DIR "${AMNEZIA_XRAY_ROOT_DIR}/linux/x86_64")
|
||||
endif()
|
||||
|
||||
set(QSIMPLECRYPTO_DIR ${CMAKE_CURRENT_LIST_DIR}/../../client/3rd/QSimpleCrypto/src)
|
||||
|
||||
|
||||
set(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../../client/3rd-prebuilt/3rd-prebuilt/openssl/")
|
||||
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
|
||||
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include")
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib")
|
||||
else()
|
||||
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
|
||||
endif()
|
||||
|
||||
|
||||
if(WIN32)
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include")
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib")
|
||||
else()
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/macos/include")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/macos/lib/libcrypto.a")
|
||||
elseif(LINUX)
|
||||
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/linux/include")
|
||||
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/linux/x86_64/libcrypto.a")
|
||||
endif()
|
||||
|
||||
set(OPENSSL_USE_STATIC_LIBS TRUE)
|
||||
|
||||
include_directories(
|
||||
${AMNEZIA_XRAY_INCLUDE_DIR}
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${QSIMPLECRYPTO_DIR}
|
||||
)
|
||||
|
||||
@@ -240,8 +189,6 @@ if(WIN32)
|
||||
gdi32
|
||||
Advapi32
|
||||
Kernel32
|
||||
${AMNEZIA_XRAY_LIB_PATH}
|
||||
${OPENSSL_LIB_CRYPTO_PATH}
|
||||
qt6keychain
|
||||
)
|
||||
|
||||
@@ -290,8 +237,6 @@ if(APPLE)
|
||||
|
||||
set(LIBS
|
||||
resolv
|
||||
${AMNEZIA_XRAY_LIB_PATH}
|
||||
${OPENSSL_LIB_CRYPTO_PATH}
|
||||
qt6keychain
|
||||
)
|
||||
|
||||
@@ -329,7 +274,6 @@ if(LINUX)
|
||||
)
|
||||
|
||||
set(LIBS
|
||||
${AMNEZIA_XRAY_LIB_PATH}
|
||||
${OPENSSL_LIB_CRYPTO_PATH}
|
||||
qt6keychain
|
||||
-static-libstdc++
|
||||
@@ -354,6 +298,12 @@ add_executable(${PROJECT} ${SOURCES} ${HEADERS} ${RESOURCES})
|
||||
target_link_libraries(${PROJECT} PRIVATE Qt6::Core Qt6::Widgets Qt6::Network Qt6::RemoteObjects Qt6::Core5Compat Qt6::DBus Qt6::Concurrent ${LIBS})
|
||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_$<UPPER_CASE:${MZ_PLATFORM_NAME}>")
|
||||
|
||||
find_package(amnezia-xray-bindings REQUIRED)
|
||||
target_link_libraries(${PROJECT} PRIVATE amnezia::xray-bindings)
|
||||
|
||||
find_package(openssl REQUIRED)
|
||||
target_link_libraries(${PROJECT} PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_compile_definitions(${PROJECT} PRIVATE "MZ_DEBUG")
|
||||
endif()
|
||||
@@ -408,10 +358,38 @@ add_custom_command(
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
|
||||
${CMAKE_SOURCE_DIR}/client/3rd-prebuilt/deploy-prebuilt/${DEPLOY_PLATFORM_PATH}
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
|
||||
if(NOT WIN32)
|
||||
find_package(awg-go REQUIRED)
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:amnezia::awg-go>
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
)
|
||||
endif()
|
||||
|
||||
find_package(openvpn REQUIRED)
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:openvpn::openvpn>
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
)
|
||||
|
||||
find_package(tun2socks REQUIRED)
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
$<TARGET_FILE:xjasonlyu::tun2socks>
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
)
|
||||
|
||||
find_package(v2ray-rules-dat REQUIRED)
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${GEOSITE_DAT_PATH}
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
)
|
||||
add_custom_command(TARGET ${PROJECT} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${GEOIP_DAT_PATH}
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
)
|
||||
|
||||
@@ -71,6 +71,7 @@ bool KillSwitch::isStrictKillSwitchEnabled()
|
||||
+ "\\" + QString(APPLICATION_NAME), QSettings::NativeFormat);
|
||||
return RegHLM.value("strictKillSwitchEnabled", false).toBool();
|
||||
#endif
|
||||
m_appSettigns->sync();
|
||||
return m_appSettigns->value("Conf/strictKillSwitchEnabled", false).toBool();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user