diff options
| author | Bug Magnet <marco.nikic@mullvad.net> | 2025-05-19 13:39:23 +0200 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2025-05-23 10:04:35 +0200 |
| commit | e99b6504f0e943dc5967d1449b90dfaed3448c66 (patch) | |
| tree | 82234ed311f06cd8e70186e22035ae4e7cf2aaff | |
| parent | 0d8fe5e10a17a3d32f079fef1ab40bfb4692d7af (diff) | |
| download | mullvadvpn-e99b6504f0e943dc5967d1449b90dfaed3448c66.tar.xz mullvadvpn-e99b6504f0e943dc5967d1449b90dfaed3448c66.zip | |
Add UITests for QUIC, add ability to block Wireguard traffic
6 files changed, 92 insertions, 15 deletions
diff --git a/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscatorPortSelectorTests.swift b/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscatorPortSelectorTests.swift index bafc9cc1b6..9fa4edb54d 100644 --- a/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscatorPortSelectorTests.swift +++ b/ios/MullvadVPNTests/MullvadREST/Relay/ObfuscatorPortSelectorTests.swift @@ -14,6 +14,7 @@ import XCTest final class ObfuscatorPortSelectorTests: XCTestCase { let defaultWireguardPort: RelayConstraint<UInt16> = .only(56) + let defaultQuicPort: RelayConstraint<UInt16> = .only(443) let sampleRelays = ServerRelaysResponseStubs.sampleRelays var tunnelSettings = LatestTunnelSettings() @@ -175,4 +176,21 @@ final class ObfuscatorPortSelectorTests: XCTestCase { XCTAssertEqual(obfuscationResult.wireguard.relays.count, sampleRelays.wireguard.relays.count) } + + // MARK: QUIC + + func testObfuscateQuicOverPort443() throws { + tunnelSettings.wireGuardObfuscation = WireGuardObfuscationSettings( + state: .quic + ) + + let obfuscationResult = try ObfuscatorPortSelector( + relays: sampleRelays + ).obfuscate( + tunnelSettings: tunnelSettings, + connectionAttemptCount: 0 + ) + + XCTAssertEqual(obfuscationResult.port, defaultQuicPort) + } } diff --git a/ios/MullvadVPNUITests/Base/BaseUITestCase.swift b/ios/MullvadVPNUITests/Base/BaseUITestCase.swift index fd27c45900..d9265ff8ea 100644 --- a/ios/MullvadVPNUITests/Base/BaseUITestCase.swift +++ b/ios/MullvadVPNUITests/Base/BaseUITestCase.swift @@ -31,6 +31,10 @@ class BaseUITestCase: XCTestCase { /// Default relay to use in tests static let testsDefaultRelayName = "se-got-wg-001" + static let testsDefaultQuicCountryName = "Relay Software Country" + static let testsDefaultQuicCityName = "Relay Software city" + static let testsDefaultQuicRelayName = "se-got-wg-881" + /// True when the current test case is capturing packets private var currentTestCaseShouldCapturePackets = false diff --git a/ios/MullvadVPNUITests/Networking/FirewallRule.swift b/ios/MullvadVPNUITests/Networking/FirewallRule.swift index 51d79c1931..eac79f9645 100644 --- a/ios/MullvadVPNUITests/Networking/FirewallRule.swift +++ b/ios/MullvadVPNUITests/Networking/FirewallRule.swift @@ -12,13 +12,13 @@ import XCTest struct FirewallRule { let fromIPAddress: String let toIPAddress: String - let protocols: [NetworkTransportProtocol] + let protocols: [TransportProtocol] /// - Parameters: /// - fromIPAddress: Block traffic originating from this source IP address. /// - toIPAddress: Block traffic to this destination IP address. /// - protocols: Protocols which should be blocked. If none is specified all will be blocked. - private init(fromIPAddress: String, toIPAddress: String, protocols: [NetworkTransportProtocol]) { + private init(fromIPAddress: String, toIPAddress: String, protocols: [TransportProtocol]) { self.fromIPAddress = fromIPAddress self.toIPAddress = toIPAddress self.protocols = protocols @@ -35,7 +35,7 @@ struct FirewallRule { return FirewallRule( fromIPAddress: deviceIPAddress, toIPAddress: apiIPAddress, - protocols: [.TCP] + protocols: [.transport(.TCP)] ) } @@ -45,7 +45,18 @@ struct FirewallRule { return FirewallRule( fromIPAddress: deviceIPAddress, toIPAddress: toIPAddress, - protocols: [.ICMP, .TCP, .UDP] + protocols: [.transport(.ICMP), .transport(.TCP), .transport(.UDP)] + ) + } + + public static func makeBlockWireGuardTrafficRule( + fromIPAddress: String, + toIPAddress: String + ) throws -> FirewallRule { + FirewallRule( + fromIPAddress: fromIPAddress, + toIPAddress: toIPAddress, + protocols: [.application(.wireguard)] ) } @@ -55,7 +66,7 @@ struct FirewallRule { return FirewallRule( fromIPAddress: deviceIPAddress, toIPAddress: toIPAddress, - protocols: [.UDP] + protocols: [.transport(.UDP)] ) } } diff --git a/ios/MullvadVPNUITests/Networking/Networking.swift b/ios/MullvadVPNUITests/Networking/Networking.swift index 93d8eba7ff..df814f70c7 100644 --- a/ios/MullvadVPNUITests/Networking/Networking.swift +++ b/ios/MullvadVPNUITests/Networking/Networking.swift @@ -10,10 +10,27 @@ import Foundation import Network import XCTest +enum TransportProtocol: Codable { + case transport(NetworkTransportProtocol) + case application(ApplicationProtocol) + + var rawValue: String { + switch self { + case let .transport(transport): transport.rawValue + case let .application(application): application.rawValue + } + } +} + +enum ApplicationProtocol: String, Codable { + case wireguard +} + enum NetworkTransportProtocol: String, Codable { case TCP = "tcp" case UDP = "udp" case ICMP = "icmp" + case ICMP6 = "icmp_v6" } enum NetworkingError: Error { diff --git a/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift b/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift index c2996c6741..f734ccd44e 100644 --- a/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift +++ b/ios/MullvadVPNUITests/Pages/TunnelControlPage.swift @@ -71,10 +71,6 @@ class TunnelControlPage: Page { return connectionAttempts } - func getInIPv4AddressLabel() -> String { - app.staticTexts[AccessibilityIdentifier.connectionPanelInAddressRow].label.components(separatedBy: ":")[0] - } - @discardableResult override init(_ app: XCUIApplication) { super.init(app) diff --git a/ios/MullvadVPNUITests/RelayTests.swift b/ios/MullvadVPNUITests/RelayTests.swift index 17c0da2d2e..fe3d18c509 100644 --- a/ios/MullvadVPNUITests/RelayTests.swift +++ b/ios/MullvadVPNUITests/RelayTests.swift @@ -179,7 +179,7 @@ class RelayTests: LoggedInWithTimeUITestCase { let connectedToIPAddress = TunnelControlPage(app) .tapRelayStatusExpandCollapseButton() - .getInIPv4AddressLabel() + .getInIPAddressFromConnectionStatus() try Networking.verifyCanAccessInternet() @@ -235,7 +235,7 @@ class RelayTests: LoggedInWithTimeUITestCase { let connectedToIPAddress = TunnelControlPage(app) .tapRelayStatusExpandCollapseButton() - .getInIPv4AddressLabel() + .getInIPAddressFromConnectionStatus() try Networking.verifyCanAccessInternet() @@ -337,6 +337,8 @@ class RelayTests: LoggedInWithTimeUITestCase { .tapWireGuardObfuscationOffCell() } + let deviceIPAddress = try FirewallClient().getDeviceIPAddress() + HeaderBar(app) .tapSettingsButton() @@ -351,18 +353,47 @@ class RelayTests: LoggedInWithTimeUITestCase { SettingsPage(app) .tapDoneButton() + startPacketCapture() + TunnelControlPage(app) - .tapConnectButton() + .tapSelectLocationButton() + + SelectLocationPage(app) + .tapLocationCellExpandButton(withName: BaseUITestCase.testsDefaultQuicCountryName) + .tapLocationCellExpandButton(withName: BaseUITestCase.testsDefaultQuicCityName) + .tapLocationCell(withName: BaseUITestCase.testsDefaultQuicRelayName) allowAddVPNConfigurationsIfAsked() TunnelControlPage(app) .waitForConnectedLabel() - try Networking.verifyCanAccessInternet() + let connectedToIPAddress = TunnelControlPage(app) + .tapRelayStatusExpandCollapseButton() + .getInIPAddressFromConnectionStatus() + let relayIPAddress = TunnelControlPage(app) + .getInIPAddressFromConnectionStatus() + + // Disconnect in order to create firewall rules, otherwise the test router cannot be reached TunnelControlPage(app) .tapDisconnectButton() + + try FirewallClient().createRule( + FirewallRule.makeBlockWireGuardTrafficRule( + fromIPAddress: deviceIPAddress, + toIPAddress: relayIPAddress + ) + ) + + // The VPN connects despite the wireguard protocol being blocked, QUIC obfuscation is in the works + TunnelControlPage(app) + .tapConnectButton() + .waitForConnectedLabel() + + try Networking.verifyCanAccessInternet() + + try generateTraffic(to: connectedToIPAddress, on: 443, assertProtocol: .UDP) } /// Test automatic switching to TCP is functioning when UDP traffic to relay is blocked. This test first connects to a realy to get the IP address of it, in order to block UDP traffic to this relay. @@ -607,10 +638,10 @@ extension RelayTests { // The capture will contain several streams where `other_addr` contains the IP the device connected to // One stream will be for the source port, the other for the destination port - let streamFromPeeerToRelay = try XCTUnwrap( + let streamFromPeerToRelay = try XCTUnwrap( capturedStreams.filter { $0.destinationAddress == connectedToIPAddress && $0.destinationPort == port }.first ) - XCTAssertTrue(streamFromPeeerToRelay.transportProtocol == transportProtocol) + XCTAssertTrue(streamFromPeerToRelay.transportProtocol == transportProtocol) } } // swiftlint:disable:this file_length |
