From c7639daf0d4e029ea682b7bc3a57053105686e07 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sat, 27 Oct 2018 00:17:28 +0200 Subject: [PATCH] Strip configuration file before attaching Of sensitive or private data. --- Passepartout-iOS/Global/IssueReporter.swift | 12 ++++++-- .../TunnelKitProvider+FileConfiguration.swift | 30 +++++++++++++++++-- .../FileConfigurationTests.swift | 7 +++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Passepartout-iOS/Global/IssueReporter.swift b/Passepartout-iOS/Global/IssueReporter.swift index 5b2d0373..4718da90 100644 --- a/Passepartout-iOS/Global/IssueReporter.swift +++ b/Passepartout-iOS/Global/IssueReporter.swift @@ -24,6 +24,7 @@ // import Foundation +import TunnelKit import MessageUI class IssueReporter: NSObject { @@ -86,8 +87,15 @@ class IssueReporter: NSObject { let attachment = DebugLog(raw: raw).decoratedData() vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.debugLog, fileName: AppConstants.IssueReporter.Filenames.debugLog) } - if let cfg = configurationURL, let attachment = try? Data(contentsOf: cfg) { - vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.configuration, fileName: AppConstants.IssueReporter.Filenames.configuration) + if let url = configurationURL { + var lines: [String] = [] + do { + _ = try TunnelKitProvider.Configuration.parsed(from: url, stripped: &lines) + if let attachment = lines.joined(separator: "\n").data(using: .utf8) { + vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.configuration, fileName: AppConstants.IssueReporter.Filenames.configuration) + } + } catch { + } } vc.mailComposeDelegate = self vc.apply(Theme.current) diff --git a/Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift b/Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift index b3d29946..c46f55dc 100644 --- a/Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift +++ b/Passepartout/Sources/VPN/TunnelKitProvider+FileConfiguration.swift @@ -62,7 +62,7 @@ extension TunnelKitProvider.Configuration { static let blockEnd = Utils.regex("^<\\/[\\w\\-]+>") } - static func parsed(from url: URL) throws -> (String, TunnelKitProvider.Configuration) { + static func parsed(from url: URL, stripped: UnsafeMutablePointer<[String]>? = nil) throws -> (String, TunnelKitProvider.Configuration) { let lines = try String(contentsOf: url).trimmedLines() var defaultProto: TunnelKitProvider.SocketType? @@ -90,7 +90,16 @@ extension TunnelKitProvider.Configuration { for line in lines { log.verbose(line) + var isHandled = false + var strippedLine = line + defer { + if isHandled { + stripped?.pointee.append(strippedLine) + } + } + Regex.blockBegin.enumerateComponents(in: line) { + isHandled = true let tag = $0.first! let from = tag.index(after: tag.startIndex) let to = tag.index(before: tag.endIndex) @@ -99,6 +108,7 @@ extension TunnelKitProvider.Configuration { currentBlock = [] } Regex.blockEnd.enumerateComponents(in: line) { + isHandled = true let tag = $0.first! let from = tag.index(tag.startIndex, offsetBy: 2) let to = tag.index(before: tag.endIndex) @@ -138,8 +148,9 @@ extension TunnelKitProvider.Configuration { currentBlock.append(line) continue } - + Regex.proto.enumerateArguments(in: line) { + isHandled = true guard let str = $0.first else { return } @@ -149,26 +160,35 @@ extension TunnelKitProvider.Configuration { } } Regex.port.enumerateArguments(in: line) { + isHandled = true guard let str = $0.first else { return } defaultPort = UInt16(str) } Regex.remote.enumerateArguments(in: line) { + isHandled = true guard let hostname = $0.first else { return } var port: UInt16? var proto: TunnelKitProvider.SocketType? + var strippedComponents = ["remote", ""] if $0.count > 1 { port = UInt16($0[1]) + strippedComponents.append($0[1]) } if $0.count > 2 { proto = TunnelKitProvider.SocketType(protoString: $0[2]) + strippedComponents.append($0[2]) } remotes.append((hostname, port, proto)) + + // replace private data + strippedLine = strippedComponents.joined(separator: " ") } Regex.cipher.enumerateArguments(in: line) { + isHandled = true guard let rawValue = $0.first else { return } @@ -178,6 +198,7 @@ extension TunnelKitProvider.Configuration { } } Regex.auth.enumerateArguments(in: line) { + isHandled = true guard let rawValue = $0.first else { return } @@ -187,24 +208,29 @@ extension TunnelKitProvider.Configuration { } } Regex.compLZO.enumerateComponents(in: line) { _ in + isHandled = true compressionFraming = .compLZO } Regex.compress.enumerateComponents(in: line) { _ in + isHandled = true compressionFraming = .compress } Regex.keyDirection.enumerateArguments(in: line) { + isHandled = true guard let arg = $0.first, let value = Int(arg) else { return } keyDirection = StaticKey.Direction(rawValue: value) } Regex.ping.enumerateArguments(in: line) { + isHandled = true guard let arg = $0.first else { return } keepAliveSeconds = TimeInterval(arg) } Regex.renegSec.enumerateArguments(in: line) { + isHandled = true guard let arg = $0.first else { return } diff --git a/PassepartoutTests-iOS/FileConfigurationTests.swift b/PassepartoutTests-iOS/FileConfigurationTests.swift index 82b82035..ead8d5b5 100644 --- a/PassepartoutTests-iOS/FileConfigurationTests.swift +++ b/PassepartoutTests-iOS/FileConfigurationTests.swift @@ -44,6 +44,13 @@ class FileConfigurationTests: XCTestCase { XCTAssertEqual(cfg.sessionConfiguration.digest, .sha1) } + func testStripped() throws { + var lines: [String] = [] + _ = try TunnelKitProvider.Configuration.parsed(from: url(withName: "pia-hungary"), stripped: &lines) + let cfg = lines.joined(separator: "\n") + print(cfg) + } + private func url(withName name: String) -> URL { return Bundle(for: FileConfigurationTests.self).url(forResource: name, withExtension: "ovpn")! }