diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 6d751491..86302d56 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -255,6 +255,20 @@ jobs:
env:
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
QT_VERSION: 6.4.3
+
+ MAC_TEAM_ID: ${{ secrets.MAC_TEAM_ID }}
+
+ MAC_APP_CERT_CERT: ${{ secrets.MAC_APP_CERT_CERT }}
+ MAC_SIGNER_ID: ${{ secrets.MAC_SIGNER_ID }}
+ MAC_APP_CERT_PW: ${{ secrets.MAC_APP_CERT_PW }}
+
+ MAC_INSTALLER_SIGNER_CERT: ${{ secrets.MAC_INSTALLER_SIGNER_CERT }}
+ MAC_INSTALLER_SIGNER_ID: ${{ secrets.MAC_INSTALLER_SIGNER_ID }}
+ MAC_INSTALL_CERT_PW: ${{ secrets.MAC_INSTALL_CERT_PW }}
+
+ APPLE_DEV_EMAIL: ${{ secrets.APPLE_DEV_EMAIL }}
+ APPLE_DEV_PASSWORD: ${{ secrets.APPLE_DEV_PASSWORD }}
+
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
@@ -295,7 +309,7 @@ jobs:
- name: 'Build project'
run: |
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
- bash deploy/build_macos.sh
+ bash deploy/build_macos.sh -n
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
@@ -318,6 +332,20 @@ jobs:
env:
QT_VERSION: 6.8.0
+
+ MAC_TEAM_ID: ${{ secrets.MAC_TEAM_ID }}
+
+ MAC_APP_CERT_CERT: ${{ secrets.MAC_APP_CERT_CERT }}
+ MAC_SIGNER_ID: ${{ secrets.MAC_SIGNER_ID }}
+ MAC_APP_CERT_PW: ${{ secrets.MAC_APP_CERT_PW }}
+
+ MAC_INSTALLER_SIGNER_CERT: ${{ secrets.MAC_INSTALLER_SIGNER_CERT }}
+ MAC_INSTALLER_SIGNER_ID: ${{ secrets.MAC_INSTALLER_SIGNER_ID }}
+ MAC_INSTALL_CERT_PW: ${{ secrets.MAC_INSTALL_CERT_PW }}
+
+ APPLE_DEV_EMAIL: ${{ secrets.APPLE_DEV_EMAIL }}
+ APPLE_DEV_PASSWORD: ${{ secrets.APPLE_DEV_PASSWORD }}
+
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
@@ -358,7 +386,7 @@ jobs:
- name: 'Build project'
run: |
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
- bash deploy/build_macos.sh
+ bash deploy/build_macos.sh -n
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
diff --git a/.gitignore b/.gitignore
index d3ebdc5c..cae7d9c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -138,3 +138,4 @@ CMakeFiles/
ios-ne-build.sh
macos-ne-build.sh
macos-signed-build.sh
+macos-with-sign-build.sh
diff --git a/client/3rd-prebuilt b/client/3rd-prebuilt
index 840b7b07..522e8d33 160000
--- a/client/3rd-prebuilt
+++ b/client/3rd-prebuilt
@@ -1 +1 @@
-Subproject commit 840b7b070e6ac8b90dda2fac6e98859b23727c0c
+Subproject commit 522e8d33a959b4d550fd0d72debf5d356a94945f
diff --git a/client/cmake/macos.cmake b/client/cmake/macos.cmake
index 7b7cd381..cedbce1b 100644
--- a/client/cmake/macos.cmake
+++ b/client/cmake/macos.cmake
@@ -18,7 +18,11 @@ set(LIBS ${LIBS}
${FW_NETWORK_EXTENSION}
)
-set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
+set_target_properties(${PROJECT} PROPERTIES
+ MACOSX_BUNDLE TRUE
+ 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)
diff --git a/client/core/controllers/coreController.cpp b/client/core/controllers/coreController.cpp
index de010fc9..5d779326 100644
--- a/client/core/controllers/coreController.cpp
+++ b/client/core/controllers/coreController.cpp
@@ -299,13 +299,10 @@ void CoreController::setQmlRoot()
void CoreController::initApiCountryModelUpdateHandler()
{
- // TODO
connect(m_serversModel.get(), &ServersModel::updateApiCountryModel, this, [this]() {
m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(),
m_serversModel->getProcessedServerData("apiServerCountryCode").toString());
});
- connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
- [this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
}
void CoreController::initContainerModelUpdateHandler()
diff --git a/client/macos/app/Info.plist b/client/macos/app/Info.plist
deleted file mode 100644
index c5372ec1..00000000
--- a/client/macos/app/Info.plist
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
-
- CFBundleAllowMixedLocalizations
-
-
- CFBundleExecutable
- ${EXECUTABLE_NAME}
-
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
-
- CFBundleInfoDictionaryVersion
- 6.0
-
- CFBundleName
- $(PRODUCT_NAME)
-
- CFBundlePackageType
- $(PRODUCT_BUNDLE_PACKAGE_TYPE)
-
- CFBundleShortVersionString
- $(MARKETING_VERSION)
-
- CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
-
- ITSAppUsesNonExemptEncryption
-
-
- LSApplicationCategoryType
- public.app-category.utilities
-
- LSMinimumSystemVersion
- ${MACOSX_DEPLOYMENT_TARGET}
-
- LSMultipleInstancesProhibited
-
-
- NSPrincipalClass
- NSApplication
-
- NSSupportsAutomaticGraphicsSwitching
-
-
-
diff --git a/client/ui/controllers/api/apiConfigsController.cpp b/client/ui/controllers/api/apiConfigsController.cpp
index 3e2b407d..1bdd3f00 100644
--- a/client/ui/controllers/api/apiConfigsController.cpp
+++ b/client/ui/controllers/api/apiConfigsController.cpp
@@ -253,10 +253,10 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode,
apiConfigObject.value(configKey::userCountryCode).toString(),
serverCountryCode,
apiConfigObject.value(configKey::serviceType).toString(),
- m_apiServicesModel->getSelectedServiceProtocol(),
+ configKey::awg, // apiConfigObject.value(configKey::serviceProtocol).toString(),
serverConfigObject.value(configKey::authData).toObject() };
- QString protocol = apiConfigObject.value(configKey::serviceProtocol).toString();
+ QString protocol = gatewayRequestData.serviceProtocol;
ProtocolData protocolData = generateProtocolData(protocol);
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
@@ -288,9 +288,8 @@ bool ApiConfigsController::revokeNativeConfig(const QString &serverCountryCode)
apiConfigObject.value(configKey::userCountryCode).toString(),
serverCountryCode,
apiConfigObject.value(configKey::serviceType).toString(),
- m_apiServicesModel->getSelectedServiceProtocol(),
- serverConfigObject.value(configKey::authData).toObject(),
- QString(APPLICATION_NAME) };
+ configKey::awg, // apiConfigObject.value(configKey::serviceProtocol).toString(),
+ serverConfigObject.value(configKey::authData).toObject() };
QJsonObject apiPayload = gatewayRequestData.toJsonObject();
diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp
index 3de0f035..139dc3c3 100644
--- a/client/vpnconnection.cpp
+++ b/client/vpnconnection.cpp
@@ -85,8 +85,7 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
IpcClient::Interface()->resetIpStack();
IpcClient::Interface()->flushDns();
- if (!m_vpnConfiguration.value(config_key::configVersion).toInt() && container != DockerContainer::Awg
- && container != DockerContainer::WireGuard) {
+ if (container != DockerContainer::Awg && container != DockerContainer::WireGuard) {
QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString();
QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString();
diff --git a/deploy/build_macos.sh b/deploy/build_macos.sh
index 68045154..5e8d7054 100644
--- a/deploy/build_macos.sh
+++ b/deploy/build_macos.sh
@@ -71,11 +71,54 @@ cmake --build . --config release --target all
KEYCHAIN_PATH="$PROJECT_DIR/mac_sign.keychain"
trap 'echo "Cleaning up mac_sign.keychain..."; security delete-keychain "$KEYCHAIN_PATH" 2>/dev/null || true; rm -f "$KEYCHAIN_PATH" 2>/dev/null || true' EXIT
KEYCHAIN=$(security default-keychain -d user | tr -d '"[:space:]"')
-security list-keychains -d user -s "$KEYCHAIN_PATH" "$KEYCHAIN" "$(security list-keychains -d user | tr '\n' ' ')"
-security create-keychain -p "" "$KEYCHAIN_PATH"
-security import "$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12" -k "$KEYCHAIN_PATH" -P "$MAC_APP_CERT_PW" -T /usr/bin/codesign
-security import "$DEPLOY_DIR/DeveloperIdInstallerCertificate.p12" -k "$KEYCHAIN_PATH" -P "$MAC_INSTALL_CERT_PW" -T /usr/bin/codesign
+
+# Build a clean list of the *existing* user key-chains. The raw output of
+# security list-keychains -d user
+# looks roughly like:
+# " \"/Users/foo/Library/Keychains/login.keychain-db\"\n \"/Library/Keychains/System.keychain\""
+# Every entry is surrounded by quotes and indented with a few blanks. Feeding
+# that verbatim back to `security list-keychains -s` inside a single quoted
+# argument leads to one long, invalid path on some systems. We therefore strip
+# the quotes and rely on the shell to split the string on whitespace so that
+# each path becomes its own argument.
+
+read -ra EXISTING_KEYCHAINS <<< "$(security list-keychains -d user | tr -d '"')"
+
+security list-keychains -d user -s "$KEYCHAIN_PATH" "$KEYCHAIN" "${EXISTING_KEYCHAINS[@]}"
+KEYCHAIN_PWD="" # Empty password keeps things simple for CI jobs
+# Create, unlock and configure the temporary key-chain so that `codesign` can
+# access the imported identities without triggering interactive prompts.
+security create-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
+# Keep the key-chain unlocked for the duration of the job (6 hours is plenty).
+security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
+security unlock-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
+
+# Import the signing certificates only when the corresponding passwords are
+# available in the environment. This allows the script to run in environments
+# where code-signing is intentionally turned off (e.g. CI jobs that just build
+# the artefacts without releasing them).
+
+if [ -n "${MAC_APP_CERT_PW-}" ]; then
+ # If the certificate is provided via environment variable, decode it.
+ if [ -n "${MAC_APP_CERT_CERT-}" ]; then
+ echo "$MAC_APP_CERT_CERT" | base64 -d > "$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12"
+ fi
+ security import "$DEPLOY_DIR/DeveloperIdApplicationCertificate.p12" \
+ -k "$KEYCHAIN_PATH" -P "$MAC_APP_CERT_PW" -A
+fi
+
+if [ -n "${MAC_INSTALL_CERT_PW-}" ]; then
+ # Same logic for the installer certificate.
+ if [ -n "${MAC_INSTALLER_SIGNER_CERT-}" ]; then
+ echo "$MAC_INSTALLER_SIGNER_CERT" | base64 -d > "$DEPLOY_DIR/DeveloperIdInstallerCertificate.p12"
+ fi
+ security import "$DEPLOY_DIR/DeveloperIdInstallerCertificate.p12" \
+ -k "$KEYCHAIN_PATH" -P "$MAC_INSTALL_CERT_PW" -A
+fi
+
+# This certificate has no password.
security import "$DEPLOY_DIR/DeveloperIDG2CA.cer" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign
+
security list-keychains -d user -s "$KEYCHAIN_PATH"
echo "____________________________________"
diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt
index f05dbb23..5ed98ab4 100644
--- a/service/CMakeLists.txt
+++ b/service/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
set(PROJECT service)
-project(${PROJECT})
+project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION})
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
diff --git a/service/server/CMakeLists.txt b/service/server/CMakeLists.txt
index 20b05acd..03128a92 100644
--- a/service/server/CMakeLists.txt
+++ b/service/server/CMakeLists.txt
@@ -162,7 +162,14 @@ if (WIN32 OR APPLE OR LINUX)
)
endif()
+set(RESOURCES)
+
if(WIN32)
+ configure_file(
+ ${CMAKE_CURRENT_LIST_DIR}/amneziavpn-service.rc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/amneziavpn-service.rc
+ )
+
set(HEADERS ${HEADERS}
${CMAKE_CURRENT_LIST_DIR}/tapcontroller_win.h
${CMAKE_CURRENT_LIST_DIR}/router_win.h
@@ -203,6 +210,10 @@ if(WIN32)
${CMAKE_CURRENT_SOURCE_DIR}/../../client/platforms/windows/windowsutils.cpp
)
+ set(RESOURCES ${RESOURCES}
+ ${CMAKE_CURRENT_BINARY_DIR}/amneziavpn-service.rc
+ )
+
set(LIBS
user32
rasapi32
@@ -308,7 +319,7 @@ include_directories(
)
-add_executable(${PROJECT} ${SOURCES} ${HEADERS})
+add_executable(${PROJECT} ${SOURCES} ${HEADERS} ${RESOURCES})
target_link_libraries(${PROJECT} PRIVATE Qt6::Core Qt6::Widgets Qt6::Network Qt6::RemoteObjects Qt6::Core5Compat Qt6::DBus ${LIBS})
target_compile_definitions(${PROJECT} PRIVATE "MZ_$")
diff --git a/service/server/amneziavpn-service.rc.in b/service/server/amneziavpn-service.rc.in
new file mode 100644
index 00000000..8ba60d38
--- /dev/null
+++ b/service/server/amneziavpn-service.rc.in
@@ -0,0 +1,38 @@
+#include
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+#define VER_COMPANYNAME_STR "AmneziaVPN"
+#define VER_FILEDESCRIPTION_STR "AmneziaVPN Service"
+#define VER_INTERNALNAME_STR VER_FILEDESCRIPTION_STR
+#define VER_LEGALCOPYRIGHT_STR "AmneziaVPN."
+#define VER_LEGALTRADEMARKS1_STR "All Rights Reserved"
+#define VER_LEGALTRADEMARKS2_STR VER_LEGALTRADEMARKS1_STR
+#define VER_ORIGINALFILENAME_STR "AmneziaVPN-service.exe"
+#define VER_PRODUCTNAME_STR VER_FILEDESCRIPTION_STR
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION @CMAKE_PROJECT_VERSION_MAJOR@,@CMAKE_PROJECT_VERSION_MINOR@,@CMAKE_PROJECT_VERSION_PATCH@,@CMAKE_PROJECT_VERSION_TWEAK@
+PRODUCTVERSION @CMAKE_PROJECT_VERSION_MAJOR@,@CMAKE_PROJECT_VERSION_MINOR@,@CMAKE_PROJECT_VERSION_PATCH@
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ BEGIN
+ VALUE "CompanyName", VER_COMPANYNAME_STR
+ VALUE "FileDescription", VER_FILEDESCRIPTION_STR
+ VALUE "FileVersion", "@CMAKE_PROJECT_VERSION@"
+ VALUE "InternalName", VER_INTERNALNAME_STR
+ VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
+ VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR
+ VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR
+ VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
+ VALUE "ProductName", VER_PRODUCTNAME_STR
+ VALUE "ProductVersion", "@CMAKE_PROJECT_VERSION@"
+ END
+ END
+
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END