diff --git a/.github/workflows/build-macos.yaml b/.github/workflows/build-macos.yaml
index 6f5acaf02..650679c3c 100644
--- a/.github/workflows/build-macos.yaml
+++ b/.github/workflows/build-macos.yaml
@@ -73,11 +73,11 @@ jobs:
pnpm build
- name: Build app
- uses: tauri-apps/tauri-action@v0
+ uses: tauri-apps/tauri-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
- args: --target universal-apple-darwin
+ args: --config src-tauri/tauri.app.conf.json --target universal-apple-darwin
# - name: Bundle Defguard CLI
# env:
diff --git a/.github/workflows/release-macos.yaml b/.github/workflows/release-macos.yaml
new file mode 100644
index 000000000..24a02f445
--- /dev/null
+++ b/.github/workflows/release-macos.yaml
@@ -0,0 +1,83 @@
+name: Build macOS dmg
+on:
+ workflow_call:
+ inputs:
+ upload_url:
+ description: 'Upload URL for release'
+ required: true
+ type: string
+
+env:
+ SQLX_OFFLINE: "1"
+
+jobs:
+ build-macos-dmg:
+ runs-on:
+ - self-hosted
+ - macOS
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ submodules: recursive
+
+ - name: Write release version
+ run: |
+ VERSION=$(echo ${GITHUB_REF_NAME#v} | cut -d '-' -f1)
+ echo Version: $VERSION
+ echo "VERSION=$VERSION" >> ${GITHUB_ENV}
+ if [ "${GITHUB_REF_TYPE}" = "tag" ]; then
+ echo "DEFGUARD_CLIENT_BUILD_VERSION=${GITHUB_REF_NAME#v}" >> ${GITHUB_ENV}
+ fi
+
+ - uses: actions/setup-node@v6
+ with:
+ node-version: 26
+
+ - uses: pnpm/action-setup@v6
+ with:
+ cache: true
+ version: 11
+
+ - name: Install Node dependencies for New UI
+ run: |
+ cd new-ui
+ pnpm install --no-frozen-lockfile
+
+ - name: Install Rust stable
+ uses: dtolnay/rust-toolchain@stable
+ with:
+ targets: aarch64-apple-darwin,x86_64-apple-darwin
+
+ - name: Set build number
+ run: |
+ sed -i '' "s,@BUILD_NUMBER@,${{ github.run_number }}," swift/extension/VPNExtension.xcodeproj/project.pbxproj
+ sed -i '' "s,@BUILD_NUMBER@,${{ github.run_number }}," src-tauri/tauri.macos.conf.json
+ sed -i '' "s,@BUILD_NUMBER@,${{ github.run_number }}," src-tauri/client-cli/Info.plist
+
+ - name: Unlock keychain
+ run: security -v unlock-keychain -p "${{ secrets.KEYCHAIN_PASSWORD }}" login.keychain
+
+ - name: Build new UI
+ run: |
+ cd new-ui
+ pnpm build
+
+ - name: Build app
+ uses: tauri-apps/tauri-action@v1
+ env:
+ APPLE_API_ISSUER: ${{ secrets.APPLE_API_KEY }}
+ APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
+ APPLE_SIGNING_IDENTITY: "Apple Distribution: defguard sp. z o.o. (82GZ7KN29J)"
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ args: --config src-tauri/tauri.dmg.conf.json --target universal-apple-darwin
+
+ - name: Upload DMG
+ uses: shogo82148/actions-upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ inputs.upload_url }}
+ asset_path: src-tauri/target/universal-apple-darwin/release/bundle/dmg/Defguard_${{ env.VERSION }}_universal.dmg
+ asset_content_type: application/x-apple-diskimage
+ overwrite: true
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 2b4d815f1..376203ccb 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -15,7 +15,7 @@ jobs:
steps:
- name: Create GitHub release
id: release
- uses: softprops/action-gh-release@v2
+ uses: softprops/action-gh-release@v3
with:
draft: true
generate_release_notes: true
@@ -113,7 +113,7 @@ jobs:
args: "--bundles deb"
- name: Upload DEB
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
@@ -132,13 +132,12 @@ jobs:
fpm_opts: "--architecture ${{ matrix.binary_arch }} --debug --output-type deb --version ${{ env.VERSION }} --package dg-linux-${{ env.VERSION }}_${{ matrix.deb_arch }}_ubuntu-22-04-lts.deb"
- name: Upload DEB
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: dg-linux-${{ env.VERSION }}_${{ matrix.deb_arch }}_ubuntu-22-04-lts.deb
- asset_name: dg-linux-${{ env.VERSION }}_${{ matrix.deb_arch }}_ubuntu-22-04-lts.deb
asset_content_type: application/octet-stream
build-linux:
@@ -227,23 +226,21 @@ jobs:
echo "deb_sha256_${{ matrix.deb_arch }}=$DEB_SHA256" >> ${GITHUB_OUTPUT}
- name: Upload RPM
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: src-tauri/target/release/bundle/rpm/defguard-client-${{ env.VERSION }}-1.${{ matrix.binary_arch }}.rpm
- asset_name: defguard-client-${{ env.VERSION }}-1.${{ matrix.binary_arch }}.rpm
asset_content_type: application/octet-stream
- name: Upload DEB
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: src-tauri/target/release/bundle/deb/defguard-client_${{ env.VERSION }}_${{ matrix.deb_arch }}.deb
- asset_name: defguard-client_${{ env.VERSION }}_${{ matrix.deb_arch }}.deb
asset_content_type: application/octet-stream
- name: Rename and tar client binary
@@ -253,13 +250,12 @@ jobs:
defguard-client-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}
- name: Upload client archive
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: defguard-client-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
- asset_name: defguard-client-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
asset_content_type: application/octet-stream
- name: Rename and tar daemon binary
@@ -269,13 +265,12 @@ jobs:
defguard-service-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}
- name: Upload daemon archive
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: defguard-service-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
- asset_name: defguard-service-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
asset_content_type: application/octet-stream
- name: Rename and tar defguard-cli binary
@@ -285,13 +280,12 @@ jobs:
defguard-cli-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}
- name: Upload defguard-cli archive
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: defguard-cli-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
- asset_name: defguard-cli-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
asset_content_type: application/octet-stream
- name: Rename and tar dg binary
@@ -301,13 +295,12 @@ jobs:
dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}
- name: Upload dg archive
- uses: actions/upload-release-asset@v1
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
- asset_name: dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.tar.gz
asset_content_type: application/octet-stream
- name: Build dg deb
@@ -317,13 +310,12 @@ jobs:
fpm_opts: "--architecture ${{ matrix.binary_arch }} --debug --output-type deb --version ${{ env.VERSION }} --package dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.deb"
- name: Upload DEB
- uses: actions/upload-release-asset@v1.0.2
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.deb
- asset_name: dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.deb
asset_content_type: application/octet-stream
- name: Build dg rpm
@@ -333,15 +325,21 @@ jobs:
fpm_opts: "--architecture ${{ matrix.binary_arch }} --debug --output-type rpm --version ${{ env.VERSION }} --package dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.rpm"
- name: Upload RPM
- uses: actions/upload-release-asset@v1.0.2
+ uses: shogo82148/actions-upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.rpm
- asset_name: dg-linux-${{ matrix.binary_arch }}-${{ github.ref_name }}.rpm
asset_content_type: application/octet-stream
+ build-macos:
+ needs:
+ - create-release
+ uses: ./.github/workflows/sbom.yml
+ with:
+ upload_url: ${{ needs.create-release.outputs.upload_url }}
+
# Builds Windows MSI and uploads it as artifact
# build-windows:
# needs:
@@ -423,7 +421,7 @@ jobs:
# - name: Sign bundle
# run: osslsigncode sign -pkcs11module /srv/codesign/certum/sc30pkcs11-3.0.6.72-MS.so -pkcs11cert ${{ secrets.CODESIGN_KEYID }} -key ${{ secrets.CODESIGN_KEYID }} -pass ${{ secrets.CODESIGN_PIN }} -h sha256 -t http://time.certum.pl/ -in Defguard_${{ env.VERSION }}_${{ matrix.cpu }}_en-US.msi -out Defguard-signed.msi
# - name: Upload installer asset
- # uses: actions/upload-release-asset@v1
+ # uses: shogo82148/actions-upload-release-asset@v1
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# with:
diff --git a/.github/workflows/sbom.yml b/.github/workflows/sbom.yml
index 64db1184b..1fae9ef4b 100644
--- a/.github/workflows/sbom.yml
+++ b/.github/workflows/sbom.yml
@@ -32,7 +32,7 @@ jobs:
submodules: recursive
- name: Create SBOM with Trivy
- uses: aquasecurity/trivy-action@0.35.0
+ uses: aquasecurity/trivy-action@v0.36.0
env:
TRIVY_SHOW_SUPPRESSED: 1
TRIVY_IGNOREFILE: "./.trivyignore.yaml"
@@ -45,7 +45,7 @@ jobs:
scanners: "vuln"
- name: Create security advisory file with Trivy
- uses: aquasecurity/trivy-action@0.35.0
+ uses: aquasecurity/trivy-action@v0.36.0
env:
TRIVY_SHOW_SUPPRESSED: 1
TRIVY_IGNOREFILE: "./.trivyignore.yaml"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c9809695c..420d90616 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -45,7 +45,7 @@ jobs:
submodules: recursive
- name: Scan code with Trivy
- uses: aquasecurity/trivy-action@0.35.0
+ uses: aquasecurity/trivy-action@v0.36.0
env:
TRIVY_SHOW_SUPPRESSED: 1
TRIVY_IGNOREFILE: "./.trivyignore.yaml"
diff --git a/.gitignore b/.gitignore
index 9688945cc..95eef0d0f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,7 +26,6 @@ dist-ssr
*.db
*.db-shm
*.db-wal
-*.provisionprofile
src-tauri/gen/
diff --git a/new-ui/package.json b/new-ui/package.json
index c216d0f51..976c6d699 100644
--- a/new-ui/package.json
+++ b/new-ui/package.json
@@ -34,7 +34,7 @@
"chart.js": "^4.5.1",
"clsx": "^2.1.1",
"dayjs": "^1.11.21",
- "motion": "^12.42.0",
+ "motion": "^12.42.2",
"p-timeout": "^7.0.1",
"prettier": "^3.9.4",
"qrcode.react": "^4.2.0",
@@ -62,6 +62,6 @@
"stylelint-config-standard-scss": "^17.0.0",
"stylelint-scss": "^7.2.0",
"typescript": "~6.0.3",
- "vite": "^8.1.1"
+ "vite": "^8.1.2"
}
}
diff --git a/new-ui/pnpm-lock.yaml b/new-ui/pnpm-lock.yaml
index cdf8b658e..8ac123eb6 100644
--- a/new-ui/pnpm-lock.yaml
+++ b/new-ui/pnpm-lock.yaml
@@ -31,7 +31,7 @@ importers:
version: 1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tanstack/router-plugin':
specifier: ^1.168.18
- version: 1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.3)(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
+ version: 1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.3)(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
'@tauri-apps/api':
specifier: ^2.11.1
version: 2.11.1
@@ -72,8 +72,8 @@ importers:
specifier: ^1.11.21
version: 1.11.21
motion:
- specifier: ^12.42.0
- version: 12.42.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ specifier: ^12.42.2
+ version: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
p-timeout:
specifier: ^7.0.1
version: 7.0.1
@@ -116,7 +116,7 @@ importers:
devDependencies:
'@tanstack/devtools-vite':
specifier: ^0.8.1
- version: 0.8.1(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
+ version: 0.8.1(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
'@types/byte-size':
specifier: ^8.1.2
version: 8.1.2
@@ -131,7 +131,7 @@ importers:
version: 19.2.3(@types/react@19.2.17)
'@vitejs/plugin-react':
specifier: ^6.0.3
- version: 6.0.3(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
+ version: 6.0.3(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
autoprefixer:
specifier: ^10.5.2
version: 10.5.2(postcss@8.5.16)
@@ -151,8 +151,8 @@ importers:
specifier: ~6.0.3
version: 6.0.3
vite:
- specifier: ^8.1.1
- version: 8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
+ specifier: ^8.1.2
+ version: 8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
packages:
@@ -1133,8 +1133,8 @@ packages:
resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
engines: {node: '>=0.3.1'}
- electron-to-chromium@1.5.382:
- resolution: {integrity: sha512-8ETaWbV6SZOrno+G93Ffd9ENsMtetqdnqj4nlfxFW90Sm5GgnuV28Kf62hqQVD6VUgzm7qFQKsTsAPmeUiU3Ug==}
+ electron-to-chromium@1.5.383:
+ resolution: {integrity: sha512-I2484/KkAvl8lm9VyjH2JnbOIV0d/UCqT7gbzs6l+o6Vmn9wgB66uVcKX+Vk6HrXtY6fbWTOEXuv8waDTuFNCw==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -1198,8 +1198,8 @@ packages:
fraction.js@5.3.4:
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
- framer-motion@12.42.0:
- resolution: {integrity: sha512-wp7EJnfWaaEScVygKv3e20udoRz+LbtxScsuTkakAxfXmt+ReC6WyPW2nINRAGvd+hG9odwcjBLyOTPjH5pBRA==}
+ framer-motion@12.42.2:
+ resolution: {integrity: sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
@@ -1579,14 +1579,14 @@ packages:
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
engines: {node: '>=8.6'}
- motion-dom@12.42.0:
- resolution: {integrity: sha512-M63h4n8R+quJdNhBwuLlgxM+OLYa9+I/T2pzDRboB9fLXRdbou+Gw7Zury+SkpaCyACP1JHSjHgZ1EgTkBr30w==}
+ motion-dom@12.42.2:
+ resolution: {integrity: sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA==}
motion-utils@12.39.0:
resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==}
- motion@12.42.0:
- resolution: {integrity: sha512-Qhwvu9sVl5/URSq5CNzwMCpSKK8Uhnrwb6VO977kZyj/wOCS7mWebJUnBoHx5cZU1Zv8a9BD5CSICWKAlrLJgA==}
+ motion@12.42.2:
+ resolution: {integrity: sha512-Atvv11yUKIid41cVrRBDVX5m8tF8kNpExRSlbpt6APClhDjtwQssgFHhQzejxw7/7YYbjHSPKBVbHo05BuJT5Q==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
@@ -1994,8 +1994,8 @@ packages:
vfile@6.0.3:
resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
- vite@8.1.1:
- resolution: {integrity: sha512-X/05/cT+VITy2AeDc1der6smvGWWREtL4hPbPTaVbjSBuuWkmNOjR6HP3NzqcQA2nF6VHGUPaFRJyft/2AE9Kg==}
+ vite@8.1.2:
+ resolution: {integrity: sha512-6YYPbRXTxx6bRXmOn7XdnQAy5DQNHhDgtjhDHI13oe4pY93kkcdGJWxpGwOm++/Wh0QpQhDrpIoVMrmrsI5AGQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -2578,7 +2578,7 @@ snapshots:
'@tanstack/devtools-event-client@0.5.0': {}
- '@tanstack/devtools-vite@0.8.1(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))':
+ '@tanstack/devtools-vite@0.8.1(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))':
dependencies:
'@tanstack/devtools-client': 0.0.8
'@tanstack/devtools-event-bus': 0.4.2
@@ -2587,7 +2587,7 @@ snapshots:
magic-string: 0.30.21
oxc-parser: 0.120.0(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)
picomatch: 4.0.4
- vite: 8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
@@ -2662,7 +2662,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@tanstack/router-plugin@1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.3)(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))':
+ '@tanstack/router-plugin@1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.3)(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))':
dependencies:
'@babel/core': 7.29.7
'@babel/template': 7.29.7
@@ -2671,11 +2671,11 @@ snapshots:
'@tanstack/router-generator': 1.167.17
'@tanstack/router-utils': 1.162.2
chokidar: 5.0.0
- unplugin: 3.3.0(rolldown@1.1.3)(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
+ unplugin: 3.3.0(rolldown@1.1.3)(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))
zod: 4.4.3
optionalDependencies:
'@tanstack/react-router': 1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
- vite: 8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
transitivePeerDependencies:
- '@farmfe/core'
- '@rspack/core'
@@ -2785,10 +2785,10 @@ snapshots:
'@ungap/structured-clone@1.3.2': {}
- '@vitejs/plugin-react@6.0.3(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))':
+ '@vitejs/plugin-react@6.0.3(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0))':
dependencies:
'@rolldown/pluginutils': 1.0.1
- vite: 8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
ajv@8.20.0:
dependencies:
@@ -2841,7 +2841,7 @@ snapshots:
dependencies:
baseline-browser-mapping: 2.10.40
caniuse-lite: 1.0.30001800
- electron-to-chromium: 1.5.382
+ electron-to-chromium: 1.5.383
node-releases: 2.0.50
update-browserslist-db: 1.2.3(browserslist@4.28.4)
@@ -2935,7 +2935,7 @@ snapshots:
diff@8.0.4: {}
- electron-to-chromium@1.5.382: {}
+ electron-to-chromium@1.5.383: {}
emoji-regex@8.0.0: {}
@@ -2991,9 +2991,9 @@ snapshots:
fraction.js@5.3.4: {}
- framer-motion@12.42.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ framer-motion@12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
dependencies:
- motion-dom: 12.42.0
+ motion-dom: 12.42.2
motion-utils: 12.39.0
tslib: 2.8.1
optionalDependencies:
@@ -3447,15 +3447,15 @@ snapshots:
braces: 3.0.3
picomatch: 2.3.2
- motion-dom@12.42.0:
+ motion-dom@12.42.2:
dependencies:
motion-utils: 12.39.0
motion-utils@12.39.0: {}
- motion@12.42.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ motion@12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
dependencies:
- framer-motion: 12.42.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ framer-motion: 12.42.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
tslib: 2.8.1
optionalDependencies:
react: 19.2.7
@@ -3881,14 +3881,14 @@ snapshots:
unist-util-is: 6.0.1
unist-util-visit-parents: 6.0.2
- unplugin@3.3.0(rolldown@1.1.3)(vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)):
+ unplugin@3.3.0(rolldown@1.1.3)(vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)):
dependencies:
'@jridgewell/remapping': 2.3.5
picomatch: 4.0.4
webpack-virtual-modules: 0.6.2
optionalDependencies:
rolldown: 1.1.3
- vite: 8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0)
update-browserslist-db@1.2.3(browserslist@4.28.4):
dependencies:
@@ -3912,7 +3912,7 @@ snapshots:
'@types/unist': 3.0.3
vfile-message: 4.0.3
- vite@8.1.1(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0):
+ vite@8.1.2(@types/node@26.0.1)(jiti@2.7.0)(sass@1.101.0):
dependencies:
lightningcss: 1.32.0
picomatch: 4.0.4
diff --git a/nix/package.nix b/nix/package.nix
index f5d7c5c4f..91c24103a 100644
--- a/nix/package.nix
+++ b/nix/package.nix
@@ -90,7 +90,7 @@
inherit pname version pnpm;
src = ../.;
fetcherVersion = 3;
- hash = "sha256-fGsjHg4FfjlH1yNzdZaXWjn07gV4j/mxv32t45RAyzM=";
+ hash = "sha256-vqBzk7E++I1A/dyOSBhzNTd1VkyVi4TMKBOMlAr0+T4=";
};
# Prefetch pnpm dependencies for the new UI (separate pnpm project).
@@ -99,7 +99,7 @@
inherit version pnpm;
src = ../new-ui;
fetcherVersion = 3;
- hash = "sha256-k2trjKO1SQB7VR2da2SwXk9D032bGQOcqcPXoBdC8hs=";
+ hash = "sha256-stgsXNlTLKkEFAf6xkMn5UXNbKGEZBWUaRFdH/iJwkM=";
};
# Pre-build the new UI frontend so Tauri can serve it as WebviewUrl::App("compact/") and "full/".
diff --git a/package.json b/package.json
index d7d5699f6..9cd965f11 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
"@stablelib/base64": "^2.0.1",
"@stablelib/x25519": "^2.0.1",
"@tanstack/query-core": "^5.101.2",
- "@tanstack/react-virtual": "^3.14.4",
+ "@tanstack/react-virtual": "^3.14.5",
"@tauri-apps/api": "^2.11.1",
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
"@tauri-apps/plugin-deep-link": "^2.4.9",
@@ -73,7 +73,7 @@
"lodash-es": "^4.18.1",
"merge-refs": "^2.0.0",
"millify": "^6.1.0",
- "motion": "^12.42.0",
+ "motion": "^12.42.2",
"p-timeout": "^7.0.1",
"prop-types": "^15.8.1",
"radash": "^12.1.1",
@@ -89,7 +89,7 @@
"react-router-dom": "^6.30.4",
"react-use-websocket": "^4.13.0",
"react-virtualized-auto-sizer": "^1.0.26",
- "recharts": "^3.9.0",
+ "recharts": "^3.9.1",
"rehype-sanitize": "^6.0.0",
"rxjs": "^7.8.2",
"use-breakpoint": "^4.0.10",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6ea977540..d4b9b7197 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -27,8 +27,8 @@ importers:
specifier: ^5.101.2
version: 5.101.2
'@tanstack/react-virtual':
- specifier: ^3.14.4
- version: 3.14.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ specifier: ^3.14.5
+ version: 3.14.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@tauri-apps/api':
specifier: ^2.11.1
version: 2.11.1
@@ -120,8 +120,8 @@ importers:
specifier: ^6.1.0
version: 6.1.0
motion:
- specifier: ^12.42.0
- version: 12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ specifier: ^12.42.2
+ version: 12.42.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
p-timeout:
specifier: ^7.0.1
version: 7.0.1
@@ -168,8 +168,8 @@ importers:
specifier: ^1.0.26
version: 1.0.26(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
recharts:
- specifier: ^3.9.0
- version: 3.9.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react-is@16.13.1)(react@19.2.7)(redux@5.0.1)
+ specifier: ^3.9.1
+ version: 3.9.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react-is@16.13.1)(react@19.2.7)(redux@5.0.1)
rehype-sanitize:
specifier: ^6.0.0
version: 6.0.0
@@ -1162,14 +1162,14 @@ packages:
peerDependencies:
react: ^18 || ^19
- '@tanstack/react-virtual@3.14.4':
- resolution: {integrity: sha512-dZzAQP2uCDAd+9sAehqmx/DcU+B91Q4Gb0aDSM7t9bJvWDyGF9sapFNW5r1gNLsHs4wTb6ScZENJeYaHxJLiOw==}
+ '@tanstack/react-virtual@3.14.5':
+ resolution: {integrity: sha512-4EKRXh7zBLkbKbFmG3AUVkircuHd+7OdT1pocJSepxtfBd3qnrJgJ5rtPkRYyo9fmyVb2+pI2xPy5oYvMLQy6A==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
- '@tanstack/virtual-core@3.17.2':
- resolution: {integrity: sha512-w43MvWvmShpb6kIC9MOoLyUkLmRTLPjt61bHWs+X29hACSpX+n8DvgZ3qM7cUfflKlRRcHR9KVJE6TmcqnQvcA==}
+ '@tanstack/virtual-core@3.17.3':
+ resolution: {integrity: sha512-8Np/TFELpI0ySuJoVmjvOrQYXH/8sTX0Biv9szhFhY39xOdAAY+smrMxjxOum/ux3eM8MUJQsEJ0/R0UpvC8dw==}
'@tauri-apps/api@2.11.1':
resolution: {integrity: sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==}
@@ -1502,8 +1502,8 @@ packages:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
- caniuse-lite@1.0.30001799:
- resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==}
+ caniuse-lite@1.0.30001800:
+ resolution: {integrity: sha512-MMHtuAz9Ys840zAY5F4k6fV5GaivZ9sPk+nz0mY+GYVzRBnYkN0mpqkSR92oWRQ19yQWo4HvBV/FnC16AJX8MA==}
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@@ -1762,8 +1762,8 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
- electron-to-chromium@1.5.381:
- resolution: {integrity: sha512-n9Wa6yB+vDsGuA8AKbl/0z7HbvWqt5jxIdvr1IUicd0ryPrk7/xzwqLv8D9AbbvZ6avVNtXYLTfmgFHkwkyelg==}
+ electron-to-chromium@1.5.383:
+ resolution: {integrity: sha512-I2484/KkAvl8lm9VyjH2JnbOIV0d/UCqT7gbzs6l+o6Vmn9wgB66uVcKX+Vk6HrXtY6fbWTOEXuv8waDTuFNCw==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@@ -1861,8 +1861,8 @@ packages:
fraction.js@5.3.4:
resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
- framer-motion@12.42.0:
- resolution: {integrity: sha512-wp7EJnfWaaEScVygKv3e20udoRz+LbtxScsuTkakAxfXmt+ReC6WyPW2nINRAGvd+hG9odwcjBLyOTPjH5pBRA==}
+ framer-motion@12.42.2:
+ resolution: {integrity: sha512-5XY9luDiu0oHfHBjpDthFMh0ES+122w6p/papSJBweMkO8Sn+PW2QaEgRblQBpWFnuvZS5qvarpt/hO2pjGmnw==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
@@ -2001,9 +2001,6 @@ packages:
resolution: {integrity: sha512-Tz7u1i95/g2x2jz81+x0FBVhBhY5aRTvD3tXXdFaljuNdzDLJ8UGNRrTcj2cgQvAg3iW/h77Fz15nLW0L0CrZw==}
engines: {node: '>=20.19.0'}
- immer@10.2.0:
- resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==}
-
immer@11.1.8:
resolution: {integrity: sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==}
@@ -2359,14 +2356,14 @@ packages:
resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==}
engines: {node: '>=10'}
- motion-dom@12.42.0:
- resolution: {integrity: sha512-M63h4n8R+quJdNhBwuLlgxM+OLYa9+I/T2pzDRboB9fLXRdbou+Gw7Zury+SkpaCyACP1JHSjHgZ1EgTkBr30w==}
+ motion-dom@12.42.2:
+ resolution: {integrity: sha512-5gIMWLp/PycBtJRJWRgjxke5n8dlvkSn2DrYW+tr3XcqAZY1xZh6BJyooJXCM8wdfM7wfMjkBJNLge1CKPUIRA==}
motion-utils@12.39.0:
resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==}
- motion@12.42.0:
- resolution: {integrity: sha512-Qhwvu9sVl5/URSq5CNzwMCpSKK8Uhnrwb6VO977kZyj/wOCS7mWebJUnBoHx5cZU1Zv8a9BD5CSICWKAlrLJgA==}
+ motion@12.42.2:
+ resolution: {integrity: sha512-Atvv11yUKIid41cVrRBDVX5m8tF8kNpExRSlbpt6APClhDjtwQssgFHhQzejxw7/7YYbjHSPKBVbHo05BuJT5Q==}
peerDependencies:
'@emotion/is-prop-valid': '*'
react: ^18.0.0 || ^19.0.0
@@ -2629,8 +2626,8 @@ packages:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
- recharts@3.9.0:
- resolution: {integrity: sha512-dCEcE9y20c8H2tkVeByrAXhhnBJk6/QLbxKmn+dJUptOfc5NMjwRh1jo0vZPRLD+5dMrHrP+hPEsfbGBMfnf5Q==}
+ recharts@3.9.1:
+ resolution: {integrity: sha512-WMcwlXcB7l+BbxiEdyClkG+1sxrMHNZpzT577LEvU4+rXPd8oTAy1wXk72hnk2KOOmxuLvw3z5DtXT7HEAydtg==}
engines: {node: '>=18'}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -3867,13 +3864,13 @@ snapshots:
'@tanstack/query-core': 5.101.2
react: 19.2.7
- '@tanstack/react-virtual@3.14.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
+ '@tanstack/react-virtual@3.14.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7)':
dependencies:
- '@tanstack/virtual-core': 3.17.2
+ '@tanstack/virtual-core': 3.17.3
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
- '@tanstack/virtual-core@3.17.2': {}
+ '@tanstack/virtual-core@3.17.3': {}
'@tauri-apps/api@2.11.1': {}
@@ -4124,7 +4121,7 @@ snapshots:
autoprefixer@10.5.2(postcss@8.5.16):
dependencies:
browserslist: 4.28.4
- caniuse-lite: 1.0.30001799
+ caniuse-lite: 1.0.30001800
fraction.js: 5.3.4
picocolors: 1.1.1
postcss: 8.5.16
@@ -4166,8 +4163,8 @@ snapshots:
browserslist@4.28.4:
dependencies:
baseline-browser-mapping: 2.10.40
- caniuse-lite: 1.0.30001799
- electron-to-chromium: 1.5.381
+ caniuse-lite: 1.0.30001800
+ electron-to-chromium: 1.5.383
node-releases: 2.0.50
update-browserslist-db: 1.2.3(browserslist@4.28.4)
@@ -4194,7 +4191,7 @@ snapshots:
camelcase@6.3.0: {}
- caniuse-lite@1.0.30001799: {}
+ caniuse-lite@1.0.30001800: {}
ccount@2.0.1: {}
@@ -4452,7 +4449,7 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
- electron-to-chromium@1.5.381: {}
+ electron-to-chromium@1.5.383: {}
emoji-regex@8.0.0: {}
@@ -4611,9 +4608,9 @@ snapshots:
fraction.js@5.3.4: {}
- framer-motion@12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ framer-motion@12.42.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
dependencies:
- motion-dom: 12.42.0
+ motion-dom: 12.42.2
motion-utils: 12.39.0
tslib: 2.8.1
optionalDependencies:
@@ -4775,8 +4772,6 @@ snapshots:
domutils: 4.0.2
entities: 8.0.0
- immer@10.2.0: {}
-
immer@11.1.8: {}
immutable@5.1.9: {}
@@ -5252,15 +5247,15 @@ snapshots:
dependencies:
brace-expansion: 2.1.1
- motion-dom@12.42.0:
+ motion-dom@12.42.2:
dependencies:
motion-utils: 12.39.0
motion-utils@12.39.0: {}
- motion@12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
+ motion@12.42.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
dependencies:
- framer-motion: 12.42.0(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
+ framer-motion: 12.42.2(@emotion/is-prop-valid@1.4.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
tslib: 2.8.1
optionalDependencies:
'@emotion/is-prop-valid': 1.4.0
@@ -5504,14 +5499,14 @@ snapshots:
readdirp@4.1.2: {}
- recharts@3.9.0(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react-is@16.13.1)(react@19.2.7)(redux@5.0.1):
+ recharts@3.9.1(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react-is@16.13.1)(react@19.2.7)(redux@5.0.1):
dependencies:
'@reduxjs/toolkit': 2.12.0(react-redux@9.3.0(@types/react@19.2.17)(react@19.2.7)(redux@5.0.1))(react@19.2.7)
clsx: 2.1.1
decimal.js-light: 2.5.1
es-toolkit: 1.49.0
eventemitter3: 5.0.4
- immer: 10.2.0
+ immer: 11.1.8
react: 19.2.7
react-dom: 19.2.7(react@19.2.7)
react-is: 16.13.1
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index e4c29f4d9..485c0695a 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -1625,6 +1625,7 @@ dependencies = [
"defguard-client-service-locations",
"defguard_wireguard_rs",
"dirs-next",
+ "dispatch2",
"futures-core",
"hyper-util",
"known-folders",
@@ -1634,6 +1635,7 @@ dependencies = [
"objc2-app-kit",
"objc2-foundation 0.3.2",
"objc2-network-extension",
+ "objc2-system-extensions",
"os_info",
"prost",
"regex",
@@ -3874,14 +3876,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libredox"
-version = "0.1.17"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
+checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652"
dependencies = [
"bitflags 2.13.0",
"libc",
"plain",
- "redox_syscall 0.8.1",
+ "redox_syscall 0.9.0",
]
[[package]]
@@ -4652,6 +4654,17 @@ dependencies = [
"objc2-core-foundation",
]
+[[package]]
+name = "objc2-system-extensions"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a00ca10e1fd778a1dd13d579afb37168422ef4bbb36b6723179c2228f6b8372c"
+dependencies = [
+ "dispatch2",
+ "objc2 0.6.4",
+ "objc2-foundation 0.3.2",
+]
+
[[package]]
name = "objc2-ui-kit"
version = "0.3.2"
@@ -5633,9 +5646,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.8.1"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7"
+checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759"
dependencies = [
"bitflags 2.13.0",
]
@@ -7082,9 +7095,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tauri"
-version = "2.11.3"
+version = "2.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2616f96cb644bf2c5c456d9de4d5d5100e592d7424c74d8b55c5cb96e359e93"
+checksum = "667b20e2726d572dea2de7370da16e188eb06008faf9a92fab7cdc46791190b5"
dependencies = [
"anyhow",
"bytes",
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index dbd72fbb7..beb94b9cc 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -140,10 +140,12 @@ x25519-dalek = { version = "2", features = [
[target.'cfg(target_os = "macos")'.dependencies]
block2 = "0.6"
+dispatch2 = { version = "0.3", optional = true }
objc2 = "0.6"
objc2-app-kit = "0.3"
objc2-foundation = "0.3"
objc2-network-extension = "0.3"
+objc2-system-extensions = { version = "0.3", optional = true }
[target.'cfg(unix)'.dependencies]
nix = { version = "0.31", features = ["user", "fs"] }
@@ -188,6 +190,7 @@ wmi = {version = "0.18", default-features = false}
# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.
# DO NOT REMOVE!!
custom-protocol = ["tauri/custom-protocol"]
+macos_installer = ["dep:dispatch2", "dep:objc2-system-extensions"]
[dev-dependencies]
tokio = { version = "1", features = ["full"] }
diff --git a/src-tauri/Defguard_Client_Mac_App_Store.provisionprofile b/src-tauri/Defguard_Client_Mac_App_Store.provisionprofile
deleted file mode 100644
index 7eaff6cd7..000000000
Binary files a/src-tauri/Defguard_Client_Mac_App_Store.provisionprofile and /dev/null differ
diff --git a/src-tauri/Defguard_VPNExtension_Mac_App_Store.provisionprofile b/src-tauri/Defguard_VPNExtension_Mac_App_Store.provisionprofile
deleted file mode 100644
index c762e5212..000000000
Binary files a/src-tauri/Defguard_VPNExtension_Mac_App_Store.provisionprofile and /dev/null differ
diff --git a/src-tauri/Installer.entitlements b/src-tauri/Installer.entitlements
new file mode 100644
index 000000000..44b8ff5ca
--- /dev/null
+++ b/src-tauri/Installer.entitlements
@@ -0,0 +1,26 @@
+
+
+
+
+ com.apple.developer.networking.networkextension
+
+ packet-tunnel-provider-systemextension
+
+ com.apple.developer.system-extension.install
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-write
+
+ com.apple.security.network.client
+
+ com.apple.application-identifier
+ 82GZ7KN29J.net.defguard
+ com.apple.developer.team-identifier
+ 82GZ7KN29J
+ com.apple.security.application-groups
+
+ group.net.defguard
+
+
+
diff --git a/src-tauri/build.rs b/src-tauri/build.rs
index 7ab8755b3..02c6245a7 100644
--- a/src-tauri/build.rs
+++ b/src-tauri/build.rs
@@ -13,6 +13,12 @@ fn main() -> Result<(), Box> {
let git2 = Git2Builder::default().branch(true).sha(true).build()?;
Emitter::default().add_instructions(&git2)?.emit()?;
+ if std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default() == "macos"
+ && std::env::var("CARGO_FEATURE_MACOS_INSTALLER").is_ok()
+ {
+ println!("cargo:rustc-link-lib=framework=SystemExtensions");
+ }
+
tauri_build::build();
Ok(())
}
diff --git a/src-tauri/client-cli/src/monitor.rs b/src-tauri/client-cli/src/monitor.rs
index 2c59266d2..d11fec626 100644
--- a/src-tauri/client-cli/src/monitor.rs
+++ b/src-tauri/client-cli/src/monitor.rs
@@ -65,7 +65,7 @@ pub async fn tear_down_stale_connections(state: &State) {
semaphore_clone.store(true, Ordering::Release);
});
spawn_runloop_and_wait_for(&semaphore);
- let _ = handle.await.unwrap();
+ let () = handle.await.unwrap();
}
#[cfg(not(target_os = "macos"))]
diff --git a/src-tauri/deny.toml b/src-tauri/deny.toml
index 5a77da65d..697ab75f7 100644
--- a/src-tauri/deny.toml
+++ b/src-tauri/deny.toml
@@ -90,6 +90,8 @@ ignore = [
{ id = "RUSTSEC-2025-0081", reason = "Tauri v2 dependency (unmaintained)" },
{ id = "RUSTSEC-2025-0098", reason = "Tauri v2 dependency (unmaintained)" },
{ id = "RUSTSEC-2025-0100", reason = "Tauri v2 dependency (unmaintained)" },
+ { id = "RUSTSEC-2026-0194", reason = "Tauri v2 dependency (unmaintained)" },
+ { id = "RUSTSEC-2026-0195", reason = "Tauri v2 dependency (unmaintained)" },
]
# If this is true, then cargo deny will use the git executable to fetch advisory database.
# If this is false, then it uses a built-in git library.
diff --git a/src-tauri/src/bin/defguard-client.rs b/src-tauri/src/bin/defguard-client.rs
index 637f4bfa9..4e66d8eac 100644
--- a/src-tauri/src/bin/defguard-client.rs
+++ b/src-tauri/src/bin/defguard-client.rs
@@ -39,6 +39,10 @@ use defguard_client::{
connection::apple::{observer_thread, spawn_runloop_and_wait_for},
database::models::get_all_tunnels_locations,
};
+#[cfg(all(target_os = "macos", feature = "macos_installer"))]
+use defguard_client::{
+ connection::apple::PLUGIN_BUNDLE_ID, system_extension::activate_system_extension,
+};
use defguard_client_core::connection::active_connections::close_all_connections;
#[cfg(target_os = "macos")]
use defguard_client_core::connection::sync_locations_and_tunnels;
@@ -93,6 +97,9 @@ async fn startup(app_handle: &AppHandle) {
}
};
}
+ #[cfg(all(target_os = "macos", feature = "macos_installer"))]
+ activate_system_extension(PLUGIN_BUNDLE_ID);
+
#[cfg(target_os = "macos")]
{
let semaphore = Arc::new(AtomicBool::new(false));
diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs
index 5fb225d04..197e37fbf 100644
--- a/src-tauri/src/commands.rs
+++ b/src-tauri/src/commands.rs
@@ -51,6 +51,7 @@ use crate::{
},
periodic::config::{do_update_instance, poll_instance_with_events},
proxy::construct_platform_header,
+ tauri_err_to_app_err,
tray::{configure_tray_icon, reload_tray_menu},
utils::{
get_location_interface_details, get_tunnel_interface_details, get_tunnel_or_location_name,
@@ -173,7 +174,7 @@ pub async fn disconnect(
);
handle
.emit(EventKey::ConnectionChanged.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
debug!("Event emitted successfully");
stop_log_watcher_task(&handle, &connection.interface_name)?;
reload_tray_menu(&handle).await;
@@ -285,7 +286,7 @@ pub async fn disconnect_locations(location_ids: Vec, handle: AppHandle) -> R
if any_disconnected {
handle
.emit(EventKey::ConnectionChanged.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
reload_tray_menu(&handle).await;
configure_tray_icon(&handle).await?;
}
@@ -313,7 +314,7 @@ async fn maybe_update_instance_config(location_id: Id, handle: &AppHandle) -> Re
transaction.commit().await?;
handle
.emit(EventKey::InstanceUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
Ok(())
}
@@ -404,7 +405,7 @@ pub async fn save_device_config(
handle
.emit(EventKey::InstanceUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
let res = SaveDeviceConfigResponse {
locations,
instance,
@@ -672,7 +673,7 @@ pub async fn update_instance(
}
app_handle
.emit(EventKey::InstanceUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
reload_tray_menu(&app_handle).await;
Ok(())
} else {
@@ -820,7 +821,7 @@ pub async fn update_location_routing(
debug!("Location routing updated for location {name}(ID: {location_id})");
handle
.emit(EventKey::LocationUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
Ok(())
}
ConnectionType::Tunnel => {
@@ -830,7 +831,7 @@ pub async fn update_location_routing(
info!("Tunnel routing updated for tunnel {location_id}");
handle
.emit(EventKey::LocationUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
Ok(())
} else {
error!("Couldn't update tunnel routing: tunnel with id {location_id} not found.");
@@ -851,7 +852,7 @@ pub async fn set_location_mfa_method(
debug!("MFA method updated for location (ID: {location_id})");
handle
.emit(EventKey::LocationUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
Ok(())
}
@@ -898,7 +899,7 @@ pub async fn delete_instance(instance_id: Id, handle: AppHandle) -> Result<(), E
handle
.emit(EventKey::InstanceUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
info!("Successfully deleted instance {instance}.");
Ok(())
}
@@ -975,7 +976,7 @@ pub async fn delete_instance(instance_id: Id, handle: AppHandle) -> Result<(), E
handle
.emit(EventKey::InstanceUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
info!("Successfully deleted instance {instance}.");
Ok(())
}
@@ -998,7 +999,7 @@ pub async fn update_tunnel(mut tunnel: Tunnel, handle: AppHandle) -> Result<
info!("The tunnel {tunnel} configuration has been updated.");
handle
.emit(EventKey::LocationUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
Ok(())
}
@@ -1009,7 +1010,7 @@ pub async fn save_tunnel(tunnel: Tunnel, handle: AppHandle) -> Result<(),
info!("The tunnel {tunnel} configuration has been saved.");
handle
.emit(EventKey::LocationUpdate.into(), ())
- .map_err(crate::tauri_err_to_app_err)?;
+ .map_err(tauri_err_to_app_err)?;
Ok(())
}
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index 477c3cb68..d8e0a064f 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -11,6 +11,8 @@ pub mod periodic;
pub mod provisioning;
pub mod service;
pub mod session_state;
+#[cfg(all(target_os = "macos", feature = "macos_installer"))]
+pub mod system_extension;
pub mod tray;
pub mod utils;
pub mod window_manager;
diff --git a/src-tauri/src/periodic/config.rs b/src-tauri/src/periodic/config.rs
index b56593248..fb6d9a2de 100644
--- a/src-tauri/src/periodic/config.rs
+++ b/src-tauri/src/periodic/config.rs
@@ -80,26 +80,22 @@ pub async fn poll_config(handle: AppHandle) {
emit_version_mismatch(&handle, instance_id, version_mismatch(&result));
emit_poll_result_events(&handle, instance_id, &instance_name, result);
debug!(
- "Finished processing configuration polling request for instance {}(ID: {})",
- instance_name, instance_id
+ "Finished processing configuration polling request for instance {instance_name}(ID: {instance_id})"
);
}
Err(Error::CoreNotEnterprise) => {
debug!(
- "Tried to contact core for instance {}(ID: {}) config but it's not enterprise, can't retrieve config",
- instance_name, instance_id
+ "Tried to contact core for instance {instance_name}(ID: {instance_id}) config but it's not enterprise, can't retrieve config"
);
}
Err(Error::NoToken) => {
debug!(
- "Instance {}(ID: {}) has no token, can't retrieve its config from the core",
- instance_name, instance_id,
+ "Instance {instance_name}(ID: {instance_id}) has no token, can't retrieve its config from the core",
);
}
Err(err) => {
error!(
- "Failed to retrieve instance {}(ID: {}) config from core: {err}",
- instance_name, instance_id
+ "Failed to retrieve instance {instance_name}(ID: {instance_id}) config from core: {err}"
);
}
}
@@ -175,15 +171,9 @@ fn emit_poll_result_events(
}
}
PollInstanceResult::ChangedWhileActive { .. } => {
- debug!(
- "Emitting config-changed event for instance {}({})",
- instance_name, instance_id,
- );
+ debug!("Emitting config-changed event for instance {instance_name}({instance_id})",);
let _ = handle.emit(EventKey::ConfigChanged.into(), instance_name);
- info!(
- "Emitted config-changed event for instance {}({})",
- instance_name, instance_id,
- );
+ info!("Emitted config-changed event for instance {instance_name}({instance_id})",);
}
}
}
diff --git a/src-tauri/src/system_extension.rs b/src-tauri/src/system_extension.rs
new file mode 100644
index 000000000..dd32ec446
--- /dev/null
+++ b/src-tauri/src/system_extension.rs
@@ -0,0 +1,110 @@
+use std::sync::{LazyLock, Mutex};
+
+use dispatch2::DispatchQueue;
+use objc2::{
+ define_class, msg_send,
+ rc::Retained,
+ runtime::{NSObjectProtocol, ProtocolObject},
+ AnyThread,
+};
+use objc2_foundation::{NSError, NSObject, NSString};
+use objc2_system_extensions::{
+ OSSystemExtensionManager, OSSystemExtensionProperties, OSSystemExtensionReplacementAction,
+ OSSystemExtensionRequest, OSSystemExtensionRequestDelegate, OSSystemExtensionRequestResult,
+};
+
+// OSSystemExtensionRequest.delegate is a `weak` property, so we must keep our delegate alive
+// for the duration of the activation handshake.
+static DELEGATE: LazyLock>>> =
+ LazyLock::new(|| Mutex::new(None));
+
+define_class!(
+ #[unsafe(super(NSObject))]
+ #[name = "DefguardSystemExtensionDelegate"]
+ struct SystemExtensionDelegate;
+
+ unsafe impl NSObjectProtocol for SystemExtensionDelegate {}
+
+ unsafe impl OSSystemExtensionRequestDelegate for SystemExtensionDelegate {
+ /// A newer version of the extension is being installed; always replace.
+ #[unsafe(method(request:actionForReplacingExtension:withExtension:))]
+ fn action_for_replacing(
+ &self,
+ _request: &OSSystemExtensionRequest,
+ _existing: &OSSystemExtensionProperties,
+ _ext: &OSSystemExtensionProperties,
+ ) -> OSSystemExtensionReplacementAction {
+ OSSystemExtensionReplacementAction::Replace
+ }
+
+ /// The extension is waiting for user approval in System Settings > Privacy & Security.
+ #[unsafe(method(requestNeedsUserApproval:))]
+ fn request_needs_user_approval(&self, _request: &OSSystemExtensionRequest) {
+ info!(
+ "VPN system extension requires user approval — open System Settings > General > \
+ Login Items & Extensions > Network Extensions to enable it."
+ );
+ }
+
+ /// Activation finished (or will finish after reboot).
+ #[unsafe(method(request:didFinishWithResult:))]
+ fn request_did_finish(
+ &self,
+ _request: &OSSystemExtensionRequest,
+ result: OSSystemExtensionRequestResult,
+ ) {
+ if result == OSSystemExtensionRequestResult::WillCompleteAfterReboot {
+ info!("VPN system extension installed; activation will complete after reboot.");
+ } else {
+ info!("VPN system extension activated successfully.");
+ }
+ }
+
+ /// Activation failed.
+ #[unsafe(method(request:didFailWithError:))]
+ fn request_did_fail(&self, _request: &OSSystemExtensionRequest, error: &NSError) {
+ error!(
+ "VPN system extension activation failed: {}",
+ error.localizedDescription()
+ );
+ }
+ }
+);
+
+impl SystemExtensionDelegate {
+ fn new() -> Retained {
+ let this = Self::alloc().set_ivars(());
+ unsafe { msg_send![super(this), init] }
+ }
+}
+
+/// Activate a system extension.
+///
+/// Safe to call on every launch — the OS ignores duplicate requests for extensions that are
+/// already active. Callbacks arrive asynchronously on the main queue via the embedded delegate.
+///
+///
+pub fn activate_system_extension(bundle_id: &str) {
+ let identifier = NSString::from_str(bundle_id);
+ let delegate = SystemExtensionDelegate::new();
+
+ // SAFETY: `delegate` is kept alive in DELEGATE for the duration of the async handshake, and
+ // the main dispatch queue lives for the whole process.
+ unsafe {
+ let request = OSSystemExtensionRequest::activationRequestForExtension_queue(
+ &identifier,
+ DispatchQueue::main(),
+ );
+ request.setDelegate(Some(ProtocolObject::from_ref(&*delegate)));
+
+ let manager = OSSystemExtensionManager::sharedManager();
+ manager.submitRequest(&request);
+ }
+
+ info!("Submitted system extension activation request for {bundle_id}.");
+
+ // Keep the delegate alive until the asynchronous callbacks are delivered.
+ if let Ok(mut guard) = DELEGATE.lock() {
+ *guard = Some(delegate);
+ }
+}
diff --git a/src-tauri/tauri.app.conf.json b/src-tauri/tauri.app.conf.json
new file mode 100644
index 000000000..3a3aba9c1
--- /dev/null
+++ b/src-tauri/tauri.app.conf.json
@@ -0,0 +1,14 @@
+{
+ "bundle": {
+ "macOS": {
+ "entitlements": "./Client.entitlements",
+ "files": {
+ "embedded.provisionprofile": "/Users/admin/Library/Developer/Xcode/UserData/Provisioning Profiles/3e2fba84-ccd2-45cc-b40e-80a9f103b5d9.provisionprofile",
+ "PlugIns/VPNExtension.appex": "../swift/extension/build/Release/VPNExtension.appex"
+ }
+ },
+ "targets": [
+ "app"
+ ]
+ }
+}
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 23f210085..3267942f7 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -8,10 +8,6 @@
"active": true,
"category": "Utility",
"copyright": "Defguard",
- "targets": [
- "deb",
- "app"
- ],
"externalBin": [],
"icon": [
"icons/32x32.png",
@@ -41,15 +37,6 @@
"template": "./resources-windows/msi/main.wxs"
}
},
- "macOS": {
- "bundleVersion": "@BUILD_NUMBER@",
- "entitlements": "./Client.entitlements",
- "files": {
- "embedded.provisionprofile": "Defguard_Client_Mac_App_Store.provisionprofile",
- "PlugIns/VPNExtension.appex": "../swift/extension/build/Release/VPNExtension.appex"
- },
- "minimumSystemVersion": "13.5"
- },
"resources": [
"resources/icons/tray/*"
],
diff --git a/src-tauri/tauri.dmg.conf.json b/src-tauri/tauri.dmg.conf.json
new file mode 100644
index 000000000..bdb8e0009
--- /dev/null
+++ b/src-tauri/tauri.dmg.conf.json
@@ -0,0 +1,23 @@
+{
+ "build": {
+ "beforeBundleCommand": {
+ "cwd": "../swift",
+ "script": "./build.sh VPNSystemExtension Installer"
+ },
+ "features": [
+ "macos_installer"
+ ]
+ },
+ "bundle": {
+ "macOS": {
+ "entitlements": "Installer.entitlements",
+ "files": {
+ "embedded.provisionprofile": "/Users/admin/Library/Developer/Xcode/UserData/Provisioning Profiles/fbbc4fe8-8738-432c-a647-484dee3f95bb.provisionprofile",
+ "Library/SystemExtensions/net.defguard.VPNExtension.systemextension": "../swift/extension/build/Installer/VPNSystemExtension.systemextension"
+ }
+ },
+ "targets": [
+ "dmg"
+ ]
+ }
+}
diff --git a/src-tauri/tauri.linux.conf.json b/src-tauri/tauri.linux.conf.json
index c2753d760..ef71faf7b 100644
--- a/src-tauri/tauri.linux.conf.json
+++ b/src-tauri/tauri.linux.conf.json
@@ -1,6 +1,9 @@
{
"productName": "defguard-client",
"bundle": {
- "longDescription": "IMPORTANT: Reboot or Re-login Required\nOn initial install the user is added to the defguard group.\nA reboot or logging out and back in is required for group membership changes to take effect.\nThis is not required on subsequent updates."
+ "longDescription": "IMPORTANT: Reboot or Re-login Required\nOn initial install the user is added to the defguard group.\nA reboot or logging out and back in is required for group membership changes to take effect.\nThis is not required on subsequent updates.",
+ "targets": [
+ "deb"
+ ]
}
}
diff --git a/src-tauri/tauri.macos.conf.json b/src-tauri/tauri.macos.conf.json
index 39e50dd04..6cecab224 100644
--- a/src-tauri/tauri.macos.conf.json
+++ b/src-tauri/tauri.macos.conf.json
@@ -4,5 +4,11 @@
"cwd": "../swift",
"script": "./build.sh"
}
+ },
+ "bundle": {
+ "macOS": {
+ "bundleVersion": "@BUILD_NUMBER@",
+ "minimumSystemVersion": "13.5"
+ }
}
}
diff --git a/src-tauri/tauri.windows.conf.json b/src-tauri/tauri.windows.conf.json
index 1644c0a1c..3865b5ce5 100644
--- a/src-tauri/tauri.windows.conf.json
+++ b/src-tauri/tauri.windows.conf.json
@@ -6,11 +6,13 @@
}
},
"bundle": {
- "targets": ["msi"],
"resources": [
"resources-windows/binaries/*",
"resources-windows/scripts/*",
"resources/icons/tray/*"
+ ],
+ "targets": [
+ "msi"
]
}
}
diff --git a/swift/build.sh b/swift/build.sh
index 9ac7564ea..24cc0898d 100755
--- a/swift/build.sh
+++ b/swift/build.sh
@@ -8,17 +8,14 @@ RUSTUP="${HOME}/.cargo/bin/rustup"
export MACOSX_DEPLOYMENT_TARGET=13.5
# Build BoringTun.
-
pushd boringtun
-for TARGET in aarch64-apple-darwin x86_64-apple-darwin
-do
+for TARGET in aarch64-apple-darwin x86_64-apple-darwin; do
${RUSTUP} target add "${TARGET}"
${CARGO} build --lib --locked --release --target ${TARGET}
done
# Create universal library.
-
mkdir -p target/universal/release
lipo -create \
target/aarch64-apple-darwin/release/libdefguard_boringtun.a \
@@ -31,7 +28,6 @@ ${CARGO} run --release --bin uniffi-bindgen -- \
target/aarch64-apple-darwin/release/libdefguard_boringtun.a target/uniffi
# Install BoringTun framework.
-
mkdir -p "${DST}"
cp -c target/uniffi/defguard_boringtun.swift "${DST}/"
rm -f -r "${DST}/defguard_boringtun.xcframework"
@@ -44,10 +40,4 @@ cp -c target/uniffi/defguard_boringtunFFI.h "${DST}/"
popd
# Build VPNExtension.
-
-# if [ "${TAURI_ENV_DEBUG}" = 'false' ]; then
- CONFIG=Release
-# else
-# CONFIG=Debug
-# fi
-xcodebuild -project extension/VPNExtension.xcodeproj -target VPNExtension -configuration ${CONFIG} build
+xcodebuild -project extension/VPNExtension.xcodeproj -target ${1:-VPNExtension} -configuration ${2:-Release} build
diff --git a/swift/extension/VPNExtension.xcodeproj/project.pbxproj b/swift/extension/VPNExtension.xcodeproj/project.pbxproj
index 04aa0ecb5..8bf7f9ef7 100644
--- a/swift/extension/VPNExtension.xcodeproj/project.pbxproj
+++ b/swift/extension/VPNExtension.xcodeproj/project.pbxproj
@@ -7,19 +7,30 @@
objects = {
/* Begin PBXBuildFile section */
+ 66C2A31F2FF503F900A2A8F7 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66CABCD72EA76D060057D1AF /* NetworkExtension.framework */; };
66CABCD82EA76D070057D1AF /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66CABCD72EA76D060057D1AF /* NetworkExtension.framework */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ 66C2A3252FF503F900A2A8F7 /* VPNSystemExtension.systemextension */ = {isa = PBXFileReference; explicitFileType = "wrapper.system-extension"; includeInIndex = 0; path = VPNSystemExtension.systemextension; sourceTree = BUILT_PRODUCTS_DIR; };
66CABCD42EA76D060057D1AF /* VPNExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = VPNExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
66CABCD72EA76D060057D1AF /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
+ 66C2A3292FF503FA00A2A8F7 /* Exceptions for "VPNExtension" folder in "VPNSystemExtension" target */ = {
+ isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
+ membershipExceptions = (
+ "Info-SysExt.plist",
+ );
+ target = 66C2A31C2FF503F900A2A8F7 /* VPNSystemExtension */;
+ };
66CABCDE2EA76D070057D1AF /* Exceptions for "VPNExtension" folder in "VPNExtension" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
- Info.plist,
+ "Info-AppExt.plist",
+ "Info-SysExt.plist",
+ main.swift,
);
target = 66CABCD32EA76D060057D1AF /* VPNExtension */;
};
@@ -41,6 +52,7 @@
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
66CABCDE2EA76D070057D1AF /* Exceptions for "VPNExtension" folder in "VPNExtension" target */,
+ 66C2A3292FF503FA00A2A8F7 /* Exceptions for "VPNExtension" folder in "VPNSystemExtension" target */,
);
path = VPNExtension;
sourceTree = "";
@@ -48,6 +60,14 @@
/* End PBXFileSystemSynchronizedRootGroup section */
/* Begin PBXFrameworksBuildPhase section */
+ 66C2A31E2FF503F900A2A8F7 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 66C2A31F2FF503F900A2A8F7 /* NetworkExtension.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
66CABCD12EA76D060057D1AF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -74,6 +94,7 @@
isa = PBXGroup;
children = (
66CABCD42EA76D060057D1AF /* VPNExtension.appex */,
+ 66C2A3252FF503F900A2A8F7 /* VPNSystemExtension.systemextension */,
);
name = Products;
sourceTree = "";
@@ -89,6 +110,30 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
+ 66C2A31C2FF503F900A2A8F7 /* VPNSystemExtension */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 66C2A3212FF503F900A2A8F7 /* Build configuration list for PBXNativeTarget "VPNSystemExtension" */;
+ buildPhases = (
+ 66C2A31D2FF503F900A2A8F7 /* Sources */,
+ 66C2A31E2FF503F900A2A8F7 /* Frameworks */,
+ 66C2A3202FF503F900A2A8F7 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ 660FE5002EA779E8006A7447 /* Defguard */,
+ 660FE50B2EA77C68006A7447 /* BoringTun */,
+ 66CABCD92EA76D070057D1AF /* VPNExtension */,
+ );
+ name = VPNSystemExtension;
+ packageProductDependencies = (
+ );
+ productName = VPNExtension;
+ productReference = 66C2A3252FF503F900A2A8F7 /* VPNSystemExtension.systemextension */;
+ productType = "com.apple.product-type.system-extension";
+ };
66CABCD32EA76D060057D1AF /* VPNExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 66CABCDF2EA76D070057D1AF /* Build configuration list for PBXNativeTarget "VPNExtension" */;
@@ -121,8 +166,11 @@
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 2600;
- LastUpgradeCheck = 2610;
+ LastUpgradeCheck = 2660;
TargetAttributes = {
+ 66C2A31C2FF503F900A2A8F7 = {
+ CreatedOnToolsVersion = 26.0.1;
+ };
66CABCD32EA76D060057D1AF = {
CreatedOnToolsVersion = 26.0.1;
};
@@ -143,11 +191,19 @@
projectRoot = "";
targets = (
66CABCD32EA76D060057D1AF /* VPNExtension */,
+ 66C2A31C2FF503F900A2A8F7 /* VPNSystemExtension */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
+ 66C2A3202FF503F900A2A8F7 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
66CABCD22EA76D060057D1AF /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -158,6 +214,13 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+ 66C2A31D2FF503F900A2A8F7 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
66CABCD02EA76D060057D1AF /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -168,6 +231,283 @@
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
+ 66C2A3222FF503F900A2A8F7 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = VPNExtension/Installer.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = "@BUILD_NUMBER@";
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_APP_SANDBOX = NO;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_INCOMING_NETWORK_CONNECTIONS = NO;
+ ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
+ ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
+ ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO;
+ ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
+ ENABLE_RESOURCE_ACCESS_CAMERA = NO;
+ ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
+ ENABLE_RESOURCE_ACCESS_LOCATION = NO;
+ ENABLE_RESOURCE_ACCESS_PRINTING = NO;
+ ENABLE_RESOURCE_ACCESS_USB = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "VPNExtension/Info-SysExt.plist";
+ INFOPLIST_KEY_CFBundleDisplayName = VPNExtension;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ "@executable_path/../../../../Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MACOSX_DEPLOYMENT_TARGET = 13.5;
+ MARKETING_VERSION = 2.1.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = net.defguard.VPNExtension;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ REGISTER_APP_GROUPS = YES;
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 66C2A3232FF503F900A2A8F7 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = VPNExtension/Installer.entitlements;
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
+ CODE_SIGN_STYLE = Manual;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = "@BUILD_NUMBER@";
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=macosx*]" = 82GZ7KN29J;
+ ENABLE_APP_SANDBOX = NO;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_INCOMING_NETWORK_CONNECTIONS = NO;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
+ ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
+ ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO;
+ ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
+ ENABLE_RESOURCE_ACCESS_CAMERA = NO;
+ ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
+ ENABLE_RESOURCE_ACCESS_LOCATION = NO;
+ ENABLE_RESOURCE_ACCESS_PRINTING = NO;
+ ENABLE_RESOURCE_ACCESS_USB = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "VPNExtension/Info-SysExt.plist";
+ INFOPLIST_KEY_CFBundleDisplayName = VPNExtension;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ "@executable_path/../../../../Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MACOSX_DEPLOYMENT_TARGET = 13.5;
+ MARKETING_VERSION = 2.1.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = net.defguard.VPNExtension;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "Defguard VPNExtension Mac DeveloperID";
+ REGISTER_APP_GROUPS = YES;
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 66C2A3242FF503F900A2A8F7 /* Installer */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = VPNExtension/Installer.entitlements;
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application: defguard sp. z o.o. (82GZ7KN29J)";
+ CODE_SIGN_STYLE = Manual;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = "@BUILD_NUMBER@";
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = "";
+ ENABLE_APP_SANDBOX = NO;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_INCOMING_NETWORK_CONNECTIONS = NO;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
+ ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
+ ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO;
+ ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
+ ENABLE_RESOURCE_ACCESS_CAMERA = NO;
+ ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
+ ENABLE_RESOURCE_ACCESS_LOCATION = NO;
+ ENABLE_RESOURCE_ACCESS_PRINTING = NO;
+ ENABLE_RESOURCE_ACCESS_USB = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "VPNExtension/Info-SysExt.plist";
+ INFOPLIST_KEY_CFBundleDisplayName = VPNExtension;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ "@executable_path/../../../../Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MACOSX_DEPLOYMENT_TARGET = 13.5;
+ MARKETING_VERSION = 2.1.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = net.defguard.VPNExtension;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "Defguard VPNExtension Mac DeveloperID";
+ REGISTER_APP_GROUPS = YES;
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Installer;
+ };
66CABCCE2EA76CD80057D1AF /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -189,6 +529,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = VPNExtension/AppStore.entitlements;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 82GZ7KN29J;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -200,6 +541,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
ONLY_ACTIVE_ARCH = YES;
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/BoringTun/defguard_boringtunFFI.h";
@@ -227,6 +569,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = VPNExtension/AppStore.entitlements;
CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 82GZ7KN29J;
@@ -238,6 +581,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
OTHER_CODE_SIGN_FLAGS = "--timestamp";
STRING_CATALOG_GENERATE_SYMBOLS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/BoringTun/defguard_boringtunFFI.h";
@@ -251,7 +595,6 @@
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
@@ -277,7 +620,6 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_ENTITLEMENTS = VPNExtension/VPNExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = "@BUILD_NUMBER@";
@@ -299,7 +641,6 @@
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
- GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
@@ -314,9 +655,8 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_INFOPLIST_FILE = YES;
- INFOPLIST_FILE = VPNExtension/Info.plist;
+ INFOPLIST_FILE = "VPNExtension/Info-AppExt.plist";
INFOPLIST_KEY_CFBundleDisplayName = VPNExtension;
- INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
@@ -349,7 +689,6 @@
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
@@ -375,7 +714,6 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- CODE_SIGN_ENTITLEMENTS = VPNExtension/VPNExtension.entitlements;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual;
COPY_PHASE_STRIP = NO;
@@ -399,7 +737,6 @@
ENABLE_RESOURCE_ACCESS_USB = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = YES;
- GCC_C_LANGUAGE_STANDARD = gnu17;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
@@ -408,9 +745,8 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
GENERATE_INFOPLIST_FILE = YES;
- INFOPLIST_FILE = VPNExtension/Info.plist;
+ INFOPLIST_FILE = "VPNExtension/Info-AppExt.plist";
INFOPLIST_KEY_CFBundleDisplayName = VPNExtension;
- INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
@@ -437,14 +773,156 @@
};
name = Release;
};
+ 66D5E73F2FF284DF0023CD03 /* Installer */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = VPNExtension/Installer.entitlements;
+ CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO;
+ DEAD_CODE_STRIPPING = YES;
+ DEVELOPMENT_TEAM = 82GZ7KN29J;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
+ OTHER_CODE_SIGN_FLAGS = "--timestamp";
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/BoringTun/defguard_boringtunFFI.h";
+ };
+ name = Installer;
+ };
+ 66D5E7402FF284DF0023CD03 /* Installer */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application: defguard sp. z o.o. (82GZ7KN29J)";
+ CODE_SIGN_STYLE = Manual;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = "@BUILD_NUMBER@";
+ DEAD_CODE_STRIPPING = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=macosx*]" = 82GZ7KN29J;
+ ENABLE_APP_SANDBOX = NO;
+ ENABLE_HARDENED_RUNTIME = YES;
+ ENABLE_INCOMING_NETWORK_CONNECTIONS = NO;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
+ ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO;
+ ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO;
+ ENABLE_RESOURCE_ACCESS_CALENDARS = NO;
+ ENABLE_RESOURCE_ACCESS_CAMERA = NO;
+ ENABLE_RESOURCE_ACCESS_CONTACTS = NO;
+ ENABLE_RESOURCE_ACCESS_LOCATION = NO;
+ ENABLE_RESOURCE_ACCESS_PRINTING = NO;
+ ENABLE_RESOURCE_ACCESS_USB = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "VPNExtension/Info-AppExt.plist";
+ INFOPLIST_KEY_CFBundleDisplayName = VPNExtension;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ "@executable_path/../../../../Frameworks",
+ );
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MACOSX_DEPLOYMENT_TARGET = 13.5;
+ MARKETING_VERSION = 2.1.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = net.defguard.VPNExtension;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = "Defguard VPNExtension Mac DeveloperID";
+ REGISTER_APP_GROUPS = YES;
+ SDKROOT = macosx;
+ SKIP_INSTALL = YES;
+ STRING_CATALOG_GENERATE_SYMBOLS = YES;
+ SWIFT_APPROACHABLE_CONCURRENCY = YES;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Installer;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ 66C2A3212FF503F900A2A8F7 /* Build configuration list for PBXNativeTarget "VPNSystemExtension" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 66C2A3222FF503F900A2A8F7 /* Debug */,
+ 66C2A3232FF503F900A2A8F7 /* Release */,
+ 66C2A3242FF503F900A2A8F7 /* Installer */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
66CABCCD2EA76CD80057D1AF /* Build configuration list for PBXProject "VPNExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
66CABCCE2EA76CD80057D1AF /* Debug */,
66CABCCF2EA76CD80057D1AF /* Release */,
+ 66D5E73F2FF284DF0023CD03 /* Installer */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
@@ -454,6 +932,7 @@
buildConfigurations = (
66CABCE02EA76D070057D1AF /* Debug */,
66CABCE12EA76D070057D1AF /* Release */,
+ 66D5E7402FF284DF0023CD03 /* Installer */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
diff --git a/swift/extension/VPNExtension/VPNExtension.entitlements b/swift/extension/VPNExtension/AppStore.entitlements
similarity index 100%
rename from swift/extension/VPNExtension/VPNExtension.entitlements
rename to swift/extension/VPNExtension/AppStore.entitlements
diff --git a/swift/extension/VPNExtension/Info.plist b/swift/extension/VPNExtension/Info-AppExt.plist
similarity index 100%
rename from swift/extension/VPNExtension/Info.plist
rename to swift/extension/VPNExtension/Info-AppExt.plist
diff --git a/swift/extension/VPNExtension/Info-SysExt.plist b/swift/extension/VPNExtension/Info-SysExt.plist
new file mode 100644
index 000000000..6de031b78
--- /dev/null
+++ b/swift/extension/VPNExtension/Info-SysExt.plist
@@ -0,0 +1,18 @@
+
+
+
+
+ NetworkExtension
+
+ NEMachServiceName
+ group.net.defguard
+ NEProviderClasses
+
+ com.apple.networkextension.packet-tunnel
+ $(PRODUCT_MODULE_NAME).PacketTunnelProvider
+
+
+ NSSystemExtensionUsageDescription
+ Defguard uses a system extension to establish and manage secure VPN connections.
+
+
diff --git a/swift/extension/VPNExtension/Installer.entitlements b/swift/extension/VPNExtension/Installer.entitlements
new file mode 100644
index 000000000..ea517b80e
--- /dev/null
+++ b/swift/extension/VPNExtension/Installer.entitlements
@@ -0,0 +1,18 @@
+
+
+
+
+ com.apple.developer.networking.networkextension
+
+ packet-tunnel-provider-systemextension
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.application-groups
+
+ group.net.defguard
+
+ com.apple.security.network.client
+
+
+
diff --git a/swift/extension/VPNExtension/main.swift b/swift/extension/VPNExtension/main.swift
new file mode 100644
index 000000000..b34a7c35f
--- /dev/null
+++ b/swift/extension/VPNExtension/main.swift
@@ -0,0 +1,9 @@
+import NetworkExtension
+
+autoreleasepool {
+ NEProvider.startSystemExtensionMode()
+}
+
+// A system extension is a standalone executable: keep the process alive so the registered
+// provider can service requests. Without this the process exits immediately after registering.
+dispatchMain()