diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 621d2d8d..a77d99f1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,6 +10,10 @@ on: - '**/*.yml' - 'Passepartout/App/fastlane/**' +concurrency: + group: ${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + jobs: run_tests: name: Run tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a72a859..a3fc7425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Ukranian translations (Dmitry Chirkin). [#243](https://github.com/passepartoutvpn/passepartout-apple/pull/243) +- OpenVPN: Full implementation of Tunnelblick XOR patch (tmthecoder). [#245](https://github.com/passepartoutvpn/passepartout-apple/pull/245), [tunnelkit#255][https://github.com/passepartoutvpn/tunnelkit/pull/255] ### Fixed diff --git a/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 703726bd..1849b8e7 100644 --- a/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -51,7 +51,7 @@ "repositoryURL": "https://github.com/passepartoutvpn/tunnelkit", "state": { "branch": null, - "revision": "0d21731e12ac316274f8c200e39f4fb48097f3dd", + "revision": "48af81e414e6f9d7ee43eb5c621a035ae939d520", "version": null } }, diff --git a/Passepartout/App/Views/EndpointAdvancedView+OpenVPN.swift b/Passepartout/App/Views/EndpointAdvancedView+OpenVPN.swift index 606c4e4a..8695fd84 100644 --- a/Passepartout/App/Views/EndpointAdvancedView+OpenVPN.swift +++ b/Passepartout/App/Views/EndpointAdvancedView+OpenVPN.swift @@ -141,10 +141,13 @@ extension EndpointAdvancedView.OpenVPNView { Text(L10n.Endpoint.Advanced.Openvpn.Items.Digest.caption) .withTrailingText($0.localizedDescription) } - settings.xor.map { - Text(Unlocalized.VPN.xor) - .withTrailingText($0.localizedDescriptionAsXOR) - } +// Text(Unlocalized.VPN.xor) +// .withTrailingText(settings.xor.localizedDescription) + themeLongContentLink( + Unlocalized.VPN.xor, + content: .constant(settings.xor.localizedLongDescription), + withPreview: settings.xor.localizedDescription + ) } header: { Text(L10n.Endpoint.Advanced.Openvpn.Sections.Communication.header) } @@ -165,10 +168,13 @@ extension EndpointAdvancedView.OpenVPNView { values: OpenVPN.Digest.available, description: \.localizedDescription ) - builder.xorMask.map { - Text(Unlocalized.VPN.xor) - .withTrailingText($0.localizedDescriptionAsXOR) - } +// Text(Unlocalized.VPN.xor) +// .withTrailingText(builder.xorMethod.localizedDescription) + themeLongContentLink( + Unlocalized.VPN.xor, + content: .constant(builder.xorMethod.localizedLongDescription), + withPreview: builder.xorMethod.localizedDescription + ) } header: { Text(L10n.Endpoint.Advanced.Openvpn.Sections.Communication.header) } @@ -309,11 +315,11 @@ extension EndpointAdvancedView.OpenVPNView { } extension OpenVPN.Configuration { - var communicationSettings: (cipher: OpenVPN.Cipher?, digest: OpenVPN.Digest?, xor: UInt8?)? { - guard cipher != nil || digest != nil || xorMask != nil else { + var communicationSettings: (cipher: OpenVPN.Cipher?, digest: OpenVPN.Digest?, xor: OpenVPN.XORMethod?)? { + guard cipher != nil || digest != nil || xorMethod != nil else { return nil } - return (cipher, digest, xorMask) + return (cipher, digest, xorMethod) } var compressionSettings: (framing: OpenVPN.CompressionFraming?, algorithm: OpenVPN.CompressionAlgorithm?)? { diff --git a/Passepartout/AppShared/L10n/OpenVPN+L10n.swift b/Passepartout/AppShared/L10n/OpenVPN+L10n.swift index 05e2d86a..638325c8 100644 --- a/Passepartout/AppShared/L10n/OpenVPN+L10n.swift +++ b/Passepartout/AppShared/L10n/OpenVPN+L10n.swift @@ -38,16 +38,6 @@ extension OpenVPN.Digest { } } -extension UInt8 { - var localizedDescriptionAsXOR: String { - let V = L10n.Global.Strings.self - guard self != 0 else { - return V.disabled - } - return String(format: "0x%02x", UInt8(self)) - } -} - extension OpenVPN.CompressionFraming { var localizedDescription: String { switch self { @@ -81,18 +71,51 @@ extension OpenVPN.CompressionAlgorithm { extension Optional where Wrapped == OpenVPN.TLSWrap { var localizedDescription: String { - let V = L10n.Endpoint.Advanced.Openvpn.Items.self - if let strategy = self?.strategy { - switch strategy { - case .auth: - return V.TlsWrapping.Value.auth - - case .crypt: - return V.TlsWrapping.Value.crypt - } - } else { + guard let strategy = self?.strategy else { return L10n.Global.Strings.disabled } + let V = L10n.Endpoint.Advanced.Openvpn.Items.self + switch strategy { + case .auth: + return V.TlsWrapping.Value.auth + + case .crypt: + return V.TlsWrapping.Value.crypt + } + } +} + +extension Optional where Wrapped == OpenVPN.XORMethod { + var localizedDescription: String { + guard let self = self else { + return L10n.Global.Strings.disabled + } + switch self { + case .xormask: + return Unlocalized.OpenVPN.XOR.xormask.rawValue + + case .xorptrpos: + return Unlocalized.OpenVPN.XOR.xorptrpos.rawValue + + case .reverse: + return Unlocalized.OpenVPN.XOR.reverse.rawValue + + case .obfuscate: + return Unlocalized.OpenVPN.XOR.obfuscate.rawValue + } + } + + var localizedLongDescription: String { + switch self { + case .xormask(let mask): + return "\(localizedDescription) \(mask.toHex())" + + case .obfuscate(let mask): + return "\(localizedDescription) \(mask.toHex())" + + default: + return localizedDescription + } } } diff --git a/Passepartout/AppShared/L10n/Unlocalized.swift b/Passepartout/AppShared/L10n/Unlocalized.swift index d096a689..6be2c370 100644 --- a/Passepartout/AppShared/L10n/Unlocalized.swift +++ b/Passepartout/AppShared/L10n/Unlocalized.swift @@ -218,6 +218,16 @@ enum Unlocalized { static let compress = "--compress" static let lzo = "LZO" + + enum XOR: String { + case xormask + + case xorptrpos + + case reverse + + case obfuscate + } } enum Network { diff --git a/PassepartoutLibrary/Package.swift b/PassepartoutLibrary/Package.swift index 704cc56b..006e69f5 100644 --- a/PassepartoutLibrary/Package.swift +++ b/PassepartoutLibrary/Package.swift @@ -24,7 +24,7 @@ let package = Package( // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), // .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", from: "5.0.0"), - .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("0d21731e12ac316274f8c200e39f4fb48097f3dd")), + .package(name: "TunnelKit", url: "https://github.com/passepartoutvpn/tunnelkit", .revision("48af81e414e6f9d7ee43eb5c621a035ae939d520")), // .package(name: "TunnelKit", path: "../../tunnelkit"), .package(url: "https://github.com/zoul/generic-json-swift", from: "2.0.0"), .package(url: "https://github.com/SwiftyBeaver/SwiftyBeaver", from: "1.9.0")