Strip configuration file before attaching

Of sensitive or private data.
This commit is contained in:
Davide De Rosa 2018-10-27 00:17:28 +02:00
parent a69c7c5733
commit c7639daf0d
3 changed files with 45 additions and 4 deletions

View File

@ -24,6 +24,7 @@
// //
import Foundation import Foundation
import TunnelKit
import MessageUI import MessageUI
class IssueReporter: NSObject { class IssueReporter: NSObject {
@ -86,8 +87,15 @@ class IssueReporter: NSObject {
let attachment = DebugLog(raw: raw).decoratedData() let attachment = DebugLog(raw: raw).decoratedData()
vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.debugLog, fileName: AppConstants.IssueReporter.Filenames.debugLog) vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.debugLog, fileName: AppConstants.IssueReporter.Filenames.debugLog)
} }
if let cfg = configurationURL, let attachment = try? Data(contentsOf: cfg) { if let url = configurationURL {
vc.addAttachmentData(attachment, mimeType: AppConstants.IssueReporter.MIME.configuration, fileName: AppConstants.IssueReporter.Filenames.configuration) 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.mailComposeDelegate = self
vc.apply(Theme.current) vc.apply(Theme.current)

View File

@ -62,7 +62,7 @@ extension TunnelKitProvider.Configuration {
static let blockEnd = Utils.regex("^<\\/[\\w\\-]+>") 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() let lines = try String(contentsOf: url).trimmedLines()
var defaultProto: TunnelKitProvider.SocketType? var defaultProto: TunnelKitProvider.SocketType?
@ -90,7 +90,16 @@ extension TunnelKitProvider.Configuration {
for line in lines { for line in lines {
log.verbose(line) log.verbose(line)
var isHandled = false
var strippedLine = line
defer {
if isHandled {
stripped?.pointee.append(strippedLine)
}
}
Regex.blockBegin.enumerateComponents(in: line) { Regex.blockBegin.enumerateComponents(in: line) {
isHandled = true
let tag = $0.first! let tag = $0.first!
let from = tag.index(after: tag.startIndex) let from = tag.index(after: tag.startIndex)
let to = tag.index(before: tag.endIndex) let to = tag.index(before: tag.endIndex)
@ -99,6 +108,7 @@ extension TunnelKitProvider.Configuration {
currentBlock = [] currentBlock = []
} }
Regex.blockEnd.enumerateComponents(in: line) { Regex.blockEnd.enumerateComponents(in: line) {
isHandled = true
let tag = $0.first! let tag = $0.first!
let from = tag.index(tag.startIndex, offsetBy: 2) let from = tag.index(tag.startIndex, offsetBy: 2)
let to = tag.index(before: tag.endIndex) let to = tag.index(before: tag.endIndex)
@ -138,8 +148,9 @@ extension TunnelKitProvider.Configuration {
currentBlock.append(line) currentBlock.append(line)
continue continue
} }
Regex.proto.enumerateArguments(in: line) { Regex.proto.enumerateArguments(in: line) {
isHandled = true
guard let str = $0.first else { guard let str = $0.first else {
return return
} }
@ -149,26 +160,35 @@ extension TunnelKitProvider.Configuration {
} }
} }
Regex.port.enumerateArguments(in: line) { Regex.port.enumerateArguments(in: line) {
isHandled = true
guard let str = $0.first else { guard let str = $0.first else {
return return
} }
defaultPort = UInt16(str) defaultPort = UInt16(str)
} }
Regex.remote.enumerateArguments(in: line) { Regex.remote.enumerateArguments(in: line) {
isHandled = true
guard let hostname = $0.first else { guard let hostname = $0.first else {
return return
} }
var port: UInt16? var port: UInt16?
var proto: TunnelKitProvider.SocketType? var proto: TunnelKitProvider.SocketType?
var strippedComponents = ["remote", "<hostname>"]
if $0.count > 1 { if $0.count > 1 {
port = UInt16($0[1]) port = UInt16($0[1])
strippedComponents.append($0[1])
} }
if $0.count > 2 { if $0.count > 2 {
proto = TunnelKitProvider.SocketType(protoString: $0[2]) proto = TunnelKitProvider.SocketType(protoString: $0[2])
strippedComponents.append($0[2])
} }
remotes.append((hostname, port, proto)) remotes.append((hostname, port, proto))
// replace private data
strippedLine = strippedComponents.joined(separator: " ")
} }
Regex.cipher.enumerateArguments(in: line) { Regex.cipher.enumerateArguments(in: line) {
isHandled = true
guard let rawValue = $0.first else { guard let rawValue = $0.first else {
return return
} }
@ -178,6 +198,7 @@ extension TunnelKitProvider.Configuration {
} }
} }
Regex.auth.enumerateArguments(in: line) { Regex.auth.enumerateArguments(in: line) {
isHandled = true
guard let rawValue = $0.first else { guard let rawValue = $0.first else {
return return
} }
@ -187,24 +208,29 @@ extension TunnelKitProvider.Configuration {
} }
} }
Regex.compLZO.enumerateComponents(in: line) { _ in Regex.compLZO.enumerateComponents(in: line) { _ in
isHandled = true
compressionFraming = .compLZO compressionFraming = .compLZO
} }
Regex.compress.enumerateComponents(in: line) { _ in Regex.compress.enumerateComponents(in: line) { _ in
isHandled = true
compressionFraming = .compress compressionFraming = .compress
} }
Regex.keyDirection.enumerateArguments(in: line) { Regex.keyDirection.enumerateArguments(in: line) {
isHandled = true
guard let arg = $0.first, let value = Int(arg) else { guard let arg = $0.first, let value = Int(arg) else {
return return
} }
keyDirection = StaticKey.Direction(rawValue: value) keyDirection = StaticKey.Direction(rawValue: value)
} }
Regex.ping.enumerateArguments(in: line) { Regex.ping.enumerateArguments(in: line) {
isHandled = true
guard let arg = $0.first else { guard let arg = $0.first else {
return return
} }
keepAliveSeconds = TimeInterval(arg) keepAliveSeconds = TimeInterval(arg)
} }
Regex.renegSec.enumerateArguments(in: line) { Regex.renegSec.enumerateArguments(in: line) {
isHandled = true
guard let arg = $0.first else { guard let arg = $0.first else {
return return
} }

View File

@ -44,6 +44,13 @@ class FileConfigurationTests: XCTestCase {
XCTAssertEqual(cfg.sessionConfiguration.digest, .sha1) 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 { private func url(withName name: String) -> URL {
return Bundle(for: FileConfigurationTests.self).url(forResource: name, withExtension: "ovpn")! return Bundle(for: FileConfigurationTests.self).url(forResource: name, withExtension: "ovpn")!
} }