From 25d84f6530fd7f271250ec0622437d5b1acebefa Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Wed, 24 Oct 2018 18:05:42 +0200 Subject: [PATCH 1/5] Add internal flag for masking private data Hardcoded to true. Private data is mostly hostname/IP addresses and routing information. --- TunnelKit/Sources/Core/CoreConfiguration.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/TunnelKit/Sources/Core/CoreConfiguration.swift b/TunnelKit/Sources/Core/CoreConfiguration.swift index 068afcf3..c8f12a8e 100644 --- a/TunnelKit/Sources/Core/CoreConfiguration.swift +++ b/TunnelKit/Sources/Core/CoreConfiguration.swift @@ -36,6 +36,7 @@ import Foundation import __TunnelKitNative +import CommonCrypto struct CoreConfiguration { static let identifier = "com.algoritmico.TunnelKit" @@ -59,6 +60,8 @@ struct CoreConfiguration { static let logsSensitiveData = false + static let masksPrivateData = true + static let usesReplayProtection = true static let tickInterval = 0.2 @@ -97,3 +100,17 @@ struct CoreConfiguration { static let keysCount = 4 } + +extension CustomStringConvertible { + var maskedDescription: String { + guard CoreConfiguration.masksPrivateData else { + return description + } + var data = description.data(using: .utf8)! + var md = Data(count: Int(CC_SHA1_DIGEST_LENGTH)) + md.withUnsafeMutableBytes { + _ = CC_SHA1(&data, CC_LONG(data.count), $0) + } + return md.toHex() + } +} From 033763f3727bf78e1291ae41a555552d54d64ea1 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Wed, 24 Oct 2018 18:06:39 +0200 Subject: [PATCH 2/5] Mask log.info --- .../Sources/AppExtension/Transport/NETCPInterface.swift | 4 ++-- .../Sources/AppExtension/Transport/NEUDPInterface.swift | 4 ++-- .../AppExtension/TunnelKitProvider+Configuration.swift | 1 - TunnelKit/Sources/AppExtension/TunnelKitProvider.swift | 4 ++-- TunnelKit/Sources/Core/SessionProxy+PushReply.swift | 8 ++++---- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift b/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift index 3fd949c9..3970702d 100644 --- a/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift +++ b/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift @@ -250,8 +250,8 @@ class NETCPLink: LinkInterface { extension NETCPSocket { override var description: String { guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else { - return impl.endpoint.description + return impl.endpoint.maskedDescription } - return "\(hostEndpoint.hostname):\(hostEndpoint.port)" + return "\(hostEndpoint.hostname.maskedDescription):\(hostEndpoint.port.maskedDescription)" } } diff --git a/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift b/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift index 5d772732..b8eb1eff 100644 --- a/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift +++ b/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift @@ -236,8 +236,8 @@ class NEUDPLink: LinkInterface { extension NEUDPSocket { override var description: String { guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else { - return impl.endpoint.description + return impl.endpoint.maskedDescription } - return "\(hostEndpoint.hostname):\(hostEndpoint.port)" + return "\(hostEndpoint.hostname.maskedDescription):\(hostEndpoint.port.maskedDescription)" } } diff --git a/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift b/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift index 42d13160..8b9b297f 100644 --- a/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift +++ b/TunnelKit/Sources/AppExtension/TunnelKitProvider+Configuration.swift @@ -527,7 +527,6 @@ extension TunnelKitProvider { log.info("App version: \(appVersion)") } -// log.info("\tAddress: \(endpoint.hostname):\(endpoint.port)") log.info("\tProtocols: \(endpointProtocols)") log.info("\tCipher: \(cipher)") log.info("\tDigest: \(digest)") diff --git a/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift b/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift index 35e73737..cd00c7e4 100644 --- a/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift +++ b/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift @@ -483,10 +483,10 @@ extension TunnelKitProvider: SessionProxyDelegate { log.info("Session did start") log.info("Returned ifconfig parameters:") - log.info("\tRemote: \(remoteAddress)") + log.info("\tRemote: \(remoteAddress.maskedDescription)") log.info("\tIPv4: \(reply.ipv4?.description ?? "not configured")") log.info("\tIPv6: \(reply.ipv6?.description ?? "not configured")") - log.info("\tDNS: \(reply.dnsServers)") + log.info("\tDNS: \(reply.dnsServers.map { $0.maskedDescription })") bringNetworkUp(remoteAddress: remoteAddress, reply: reply) { (error) in if let error = error { diff --git a/TunnelKit/Sources/Core/SessionProxy+PushReply.swift b/TunnelKit/Sources/Core/SessionProxy+PushReply.swift index 4fc87a62..2f294140 100644 --- a/TunnelKit/Sources/Core/SessionProxy+PushReply.swift +++ b/TunnelKit/Sources/Core/SessionProxy+PushReply.swift @@ -62,7 +62,7 @@ public struct IPv4Settings: CustomStringConvertible { /// :nodoc: public var description: String { - return "{\(destination)/\(mask) \(gateway ?? "default")}" + return "{\(destination.maskedDescription)/\(mask.maskedDescription) \(gateway?.maskedDescription ?? "default")}" } } @@ -82,7 +82,7 @@ public struct IPv4Settings: CustomStringConvertible { /// :nodoc: public var description: String { - return "addr \(address) netmask \(addressMask) gw \(defaultGateway) routes \(routes)" + return "addr \(address.maskedDescription) netmask \(addressMask.maskedDescription) gw \(defaultGateway.maskedDescription) routes \(routes.map { $0.maskedDescription })" } } @@ -111,7 +111,7 @@ public struct IPv6Settings: CustomStringConvertible { /// :nodoc: public var description: String { - return "{\(destination)/\(prefixLength) \(gateway ?? "default")}" + return "{\(destination.maskedDescription)/\(prefixLength.maskedDescription) \(gateway?.maskedDescription ?? "default")}" } } @@ -131,7 +131,7 @@ public struct IPv6Settings: CustomStringConvertible { /// :nodoc: public var description: String { - return "addr \(address)/\(addressPrefixLength) gw \(defaultGateway) routes \(routes)" + return "addr \(address.maskedDescription)/\(addressPrefixLength.maskedDescription) gw \(defaultGateway.maskedDescription) routes \(routes.map { $0.maskedDescription })" } } From ae85337e91ceaba5ec535a6334f78817e0a95ed9 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Wed, 24 Oct 2018 18:25:04 +0200 Subject: [PATCH 3/5] Mask log.debug --- TunnelKit/Sources/AppExtension/ConnectionStrategy.swift | 8 ++++---- TunnelKit/Sources/AppExtension/InterfaceObserver.swift | 2 +- .../Sources/AppExtension/Transport/NETCPInterface.swift | 4 ++-- .../Sources/AppExtension/Transport/NEUDPInterface.swift | 4 ++-- TunnelKit/Sources/AppExtension/TunnelKitProvider.swift | 2 +- TunnelKit/Sources/Core/SessionProxy.swift | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/TunnelKit/Sources/AppExtension/ConnectionStrategy.swift b/TunnelKit/Sources/AppExtension/ConnectionStrategy.swift index 464dcb45..52daa701 100644 --- a/TunnelKit/Sources/AppExtension/ConnectionStrategy.swift +++ b/TunnelKit/Sources/AppExtension/ConnectionStrategy.swift @@ -70,7 +70,7 @@ class ConnectionStrategy { // reuse preferred address if let preferredAddress = preferredAddress { - log.debug("Pick preferred address: \(preferredAddress)") + log.debug("Pick preferred address: \(preferredAddress.maskedDescription)") let socket = provider.createSocket(to: preferredAddress, protocol: currentProtocol()) completionHandler(socket, nil) return @@ -78,21 +78,21 @@ class ConnectionStrategy { // use any resolved address if prefersResolvedAddresses, let resolvedAddress = anyResolvedAddress() { - log.debug("Pick resolved address: \(resolvedAddress)") + log.debug("Pick resolved address: \(resolvedAddress.maskedDescription)") let socket = provider.createSocket(to: resolvedAddress, protocol: currentProtocol()) completionHandler(socket, nil) return } // fall back to DNS - log.debug("DNS resolve hostname: \(hostname)") + log.debug("DNS resolve hostname: \(hostname.maskedDescription)") DNSResolver.resolve(hostname, timeout: timeout, queue: queue) { (addresses, error) in // refresh resolved addresses if let resolved = addresses, !resolved.isEmpty { self.resolvedAddresses = resolved - log.debug("DNS resolved addresses: \(resolved)") + log.debug("DNS resolved addresses: \(resolved.map { $0.maskedDescription })") } else { log.error("DNS resolution failed!") } diff --git a/TunnelKit/Sources/AppExtension/InterfaceObserver.swift b/TunnelKit/Sources/AppExtension/InterfaceObserver.swift index 49b7f647..00fb46b4 100644 --- a/TunnelKit/Sources/AppExtension/InterfaceObserver.swift +++ b/TunnelKit/Sources/AppExtension/InterfaceObserver.swift @@ -75,7 +75,7 @@ class InterfaceObserver: NSObject { let currentWifiName = currentWifiNetworkName() if (currentWifiName != lastWifiName) { if let current = currentWifiName { - log.debug("SSID is now '\(current)'") + log.debug("SSID is now '\(current.maskedDescription)'") if let last = lastWifiName, (current != last) { queue?.async { NotificationCenter.default.post(name: .__InterfaceObserverDidDetectWifiChange, object: nil) diff --git a/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift b/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift index 3970702d..d8b9e106 100644 --- a/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift +++ b/TunnelKit/Sources/AppExtension/Transport/NETCPInterface.swift @@ -137,9 +137,9 @@ class NETCPSocket: NSObject, GenericSocket { switch keyPath { case #keyPath(NWTCPConnection.state): if let resolvedEndpoint = impl.remoteAddress { - log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint) -> \(resolvedEndpoint))") + log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint.maskedDescription) -> \(resolvedEndpoint.maskedDescription))") } else { - log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint) -> in progress)") + log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint.maskedDescription) -> in progress)") } switch impl.state { diff --git a/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift b/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift index b8eb1eff..10bc3314 100644 --- a/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift +++ b/TunnelKit/Sources/AppExtension/Transport/NEUDPInterface.swift @@ -137,9 +137,9 @@ class NEUDPSocket: NSObject, GenericSocket { switch keyPath { case #keyPath(NWUDPSession.state): if let resolvedEndpoint = impl.resolvedEndpoint { - log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint) -> \(resolvedEndpoint))") + log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint.maskedDescription) -> \(resolvedEndpoint.maskedDescription))") } else { - log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint) -> in progress)") + log.debug("Socket state is \(impl.state) (endpoint: \(impl.endpoint.maskedDescription) -> in progress)") } switch impl.state { diff --git a/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift b/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift index cd00c7e4..a8c35942 100644 --- a/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift +++ b/TunnelKit/Sources/AppExtension/TunnelKitProvider.swift @@ -602,7 +602,7 @@ extension TunnelKitProvider { private func logCurrentSSID() { if let ssid = observer.currentWifiNetworkName() { - log.debug("Current SSID: '\(ssid)'") + log.debug("Current SSID: '\(ssid.maskedDescription)'") } else { log.debug("Current SSID: none (disconnected from WiFi)") } diff --git a/TunnelKit/Sources/Core/SessionProxy.swift b/TunnelKit/Sources/Core/SessionProxy.swift index e554ff8c..c9ff7eb5 100644 --- a/TunnelKit/Sources/Core/SessionProxy.swift +++ b/TunnelKit/Sources/Core/SessionProxy.swift @@ -856,7 +856,7 @@ public class SessionProxy { return } reply = optionalReply - log.debug("Received PUSH_REPLY: \"\(reply)\"") + log.debug("Received PUSH_REPLY: \"\(reply.maskedDescription)\"") } catch let e { deferStop(.shutdown, e) return From b35fb34da56003c38fa55bdadb3837da9aedf883 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Wed, 24 Oct 2018 18:49:15 +0200 Subject: [PATCH 4/5] Cap masked hash to 16 hexes --- TunnelKit/Sources/Core/CoreConfiguration.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TunnelKit/Sources/Core/CoreConfiguration.swift b/TunnelKit/Sources/Core/CoreConfiguration.swift index c8f12a8e..c284d2f1 100644 --- a/TunnelKit/Sources/Core/CoreConfiguration.swift +++ b/TunnelKit/Sources/Core/CoreConfiguration.swift @@ -111,6 +111,6 @@ extension CustomStringConvertible { md.withUnsafeMutableBytes { _ = CC_SHA1(&data, CC_LONG(data.count), $0) } - return md.toHex() + return "#\(md.toHex().prefix(16))#" } } From e26f3105117b37f6bebc2394b4ebfc0e3874855f Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Wed, 24 Oct 2018 18:56:11 +0200 Subject: [PATCH 5/5] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c50e8a4..d0bc2881 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Configuration key `lastErrorKey` for reporting errors to host app. [#40](https://github.com/keeshux/tunnelkit/pull/40) - Server extended key usage validation (EKU). [#27](https://github.com/keeshux/tunnelkit/issues/27) +### Changed + +- Potentially private data (e.g. Internet addresses) is now masked in debug log. [#42](https://github.com/keeshux/tunnelkit/pull/42) + ### Fixed - CA file was not closed after MD5 calculation when using PIA patches.