summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJon Petersson <jon.petersson@mullvad.net>2026-04-23 10:09:12 +0200
committerJon Petersson <jon.petersson@mullvad.net>2026-04-23 10:24:03 +0200
commit7c78e43f90bc39609f5e84d369d31a19739ecae0 (patch)
treeb2ea3a92c449e7bf3dee2d8ccf9f13d8a013c014
parent0e13ae57274fa9fd6a83e971b5b9358a925080a5 (diff)
downloadmullvadvpn-fix-invalid-shadowsocks-ciphers-crashing.tar.xz
mullvadvpn-fix-invalid-shadowsocks-ciphers-crashing.zip
Fix invalid shadowsocks ciphers crashing the appfix-invalid-shadowsocks-ciphers-crashing
-rw-r--r--ios/MullvadRESTTests/MullvadApiTests.swift5
-rw-r--r--ios/MullvadRESTTests/RelayListCacheTests.swift3
-rw-r--r--ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift8
-rw-r--r--ios/MullvadRustRuntime/MullvadConnectionModeProvider.swift12
-rw-r--r--ios/MullvadVPN/AppDelegate.swift4
-rw-r--r--ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift4
-rw-r--r--ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift4
7 files changed, 30 insertions, 10 deletions
diff --git a/ios/MullvadRESTTests/MullvadApiTests.swift b/ios/MullvadRESTTests/MullvadApiTests.swift
index d55ed2d5d5..ca62b7f25a 100644
--- a/ios/MullvadRESTTests/MullvadApiTests.swift
+++ b/ios/MullvadRESTTests/MullvadApiTests.swift
@@ -47,9 +47,8 @@ class MullvadApiTests: XCTestCase {
disableTls: true,
shadowsocksProvider: shadowsocksLoader,
accessMethodWrapper: initAccessMethodSettingsWrapper(
- methods:
- accessMethodsRepository
- .fetchAll()
+ methods: accessMethodsRepository.fetchAll(),
+ validShadowsocksCiphers: []
),
accessMethodChangeListeners: []
)
diff --git a/ios/MullvadRESTTests/RelayListCacheTests.swift b/ios/MullvadRESTTests/RelayListCacheTests.swift
index 7a04ae85e0..18b530f6b4 100644
--- a/ios/MullvadRESTTests/RelayListCacheTests.swift
+++ b/ios/MullvadRESTTests/RelayListCacheTests.swift
@@ -110,7 +110,8 @@ class RelayListCacheTests: XCTestCase {
disableTls: true,
shadowsocksProvider: shadowsocksLoader,
accessMethodWrapper: initAccessMethodSettingsWrapper(
- methods: accessMethodsRepository.fetchAll()
+ methods: accessMethodsRepository.fetchAll(),
+ validShadowsocksCiphers: []
),
accessMethodChangeListeners: []
)
diff --git a/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift b/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift
index 4f1ad7a491..488b1f760b 100644
--- a/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift
+++ b/ios/MullvadRustRuntime/MullvadAccessMethodReceiver.swift
@@ -13,13 +13,16 @@ import MullvadTypes
public class MullvadAccessMethodReceiver {
private var cancellables = Set<Combine.AnyCancellable>()
let apiContext: MullvadApiContext
+ let validShadowsocksCiphers: [String]
public init(
apiContext: MullvadApiContext,
+ validShadowsocksCiphers: [String],
accessMethodsDataSource: AnyPublisher<[PersistentAccessMethod], Never>,
requestDataSource: AnyPublisher<PersistentAccessMethod, Never>
) {
self.apiContext = apiContext
+ self.validShadowsocksCiphers = validShadowsocksCiphers
requestDataSource.sink { [weak self] latestReachable in
self?.saveLastReachable(latestReachable)
@@ -36,7 +39,10 @@ public class MullvadAccessMethodReceiver {
}
private func updateAccessMethods(_ accessMethods: [PersistentAccessMethod]) {
- let settingsWrapper = initAccessMethodSettingsWrapper(methods: accessMethods)
+ let settingsWrapper = initAccessMethodSettingsWrapper(
+ methods: accessMethods,
+ validShadowsocksCiphers: validShadowsocksCiphers
+ )
mullvad_api_update_access_methods(apiContext.context, settingsWrapper)
}
}
diff --git a/ios/MullvadRustRuntime/MullvadConnectionModeProvider.swift b/ios/MullvadRustRuntime/MullvadConnectionModeProvider.swift
index ede79eb1e8..8a6f804485 100644
--- a/ios/MullvadRustRuntime/MullvadConnectionModeProvider.swift
+++ b/ios/MullvadRustRuntime/MullvadConnectionModeProvider.swift
@@ -8,7 +8,7 @@
import MullvadTypes
-public func initAccessMethodSettingsWrapper(methods: [PersistentAccessMethod])
+public func initAccessMethodSettingsWrapper(methods: [PersistentAccessMethod], validShadowsocksCiphers: [String])
-> SwiftAccessMethodSettingsWrapper
{
// 1. Get all the built in access methods, it is expected that they are always available
@@ -28,11 +28,19 @@ public func initAccessMethodSettingsWrapper(methods: [PersistentAccessMethod])
var rawCustomMethods = ContiguousArray<UnsafeRawPointer?>([])
// 4. Convert the custom access methods (all takes different parameters)
for method in customMethods {
+ // Make sure we only use access methods with valud ciphers.
+ if case .shadowsocks(let config) = method.proxyConfiguration {
+ guard validShadowsocksCiphers.contains(config.cipher) else {
+ continue
+ }
+ }
+
let rawMethod = convertAccessMethod(accessMethod: method)
rawCustomMethods.append(rawMethod)
}
// 5. Reunite them all in one, and pass it to rust
+ let customMethodCount = rawCustomMethods.count
return rawCustomMethods.withUnsafeMutableBufferPointer(
{
init_access_method_settings_wrapper(
@@ -40,7 +48,7 @@ public func initAccessMethodSettingsWrapper(methods: [PersistentAccessMethod])
bridgesMethodRaw,
encryptedDNSMethodRaw,
$0.baseAddress!,
- UInt(customMethods.count)
+ UInt(customMethodCount)
)
}
)
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift
index d758832d7d..a177b48b9b 100644
--- a/ios/MullvadVPN/AppDelegate.swift
+++ b/ios/MullvadVPN/AppDelegate.swift
@@ -101,7 +101,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
shadowsocksCacheCleaner = ShadowsocksCacheCleaner(cache: shadowsocksCache)
let opaqueAccessMethodSettingsWrapper = initAccessMethodSettingsWrapper(
- methods: accessMethodRepository.fetchAll()
+ methods: accessMethodRepository.fetchAll(),
+ validShadowsocksCiphers: accessMethodRepository.shadowsocksCiphers
)
// swift-format-ignore: NeverUseForceTry
@@ -116,6 +117,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
accessMethodReceiver = MullvadAccessMethodReceiver(
apiContext: apiContext,
+ validShadowsocksCiphers: accessMethodRepository.shadowsocksCiphers,
accessMethodsDataSource: accessMethodRepository.accessMethodsPublisher,
requestDataSource: accessMethodRepository.requestAccessMethodPublisher
)
diff --git a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
index 8d077314e2..3d68b63d69 100644
--- a/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
+++ b/ios/MullvadVPNTests/MullvadVPN/TunnelManager/TunnelManagerTests.swift
@@ -48,7 +48,9 @@ class TunnelManagerTests: XCTestCase {
)
let opaqueAccessMethodSettingsWrapper = initAccessMethodSettingsWrapper(
- methods: AccessMethodRepositoryStub.stub.fetchAll())
+ methods: AccessMethodRepositoryStub.stub.fetchAll(),
+ validShadowsocksCiphers: []
+ )
apiContext = try MullvadApiContext(
host: REST.defaultAPIHostname,
diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
index fd2ee58de0..1095aaea28 100644
--- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
+++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift
@@ -242,7 +242,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
shadowsocksCacheCleaner = ShadowsocksCacheCleaner(cache: shadowsocksCache)
let opaqueAccessMethodSettingsWrapper = initAccessMethodSettingsWrapper(
- methods: accessMethodRepository.fetchAll()
+ methods: accessMethodRepository.fetchAll(),
+ validShadowsocksCiphers: accessMethodRepository.shadowsocksCiphers
)
// swift-format-ignore: NeverUseForceTry
@@ -261,6 +262,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
) {
accessMethodReceiver = MullvadAccessMethodReceiver(
apiContext: apiContext,
+ validShadowsocksCiphers: accessMethodRepository.shadowsocksCiphers,
accessMethodsDataSource: accessMethodRepository.accessMethodsPublisher,
requestDataSource: accessMethodRepository.requestAccessMethodPublisher
)