Merge pull request #42 from keeshux/mask-private-debug-data

Mask private debug data
This commit is contained in:
Davide De Rosa 2018-10-24 19:40:47 +02:00 committed by GitHub
commit 8b78a64dbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 42 additions and 22 deletions

View File

@ -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) - 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) - 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 ### Fixed
- CA file was not closed after MD5 calculation when using PIA patches. - CA file was not closed after MD5 calculation when using PIA patches.

View File

@ -70,7 +70,7 @@ class ConnectionStrategy {
// reuse preferred address // reuse preferred address
if let preferredAddress = preferredAddress { 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()) let socket = provider.createSocket(to: preferredAddress, protocol: currentProtocol())
completionHandler(socket, nil) completionHandler(socket, nil)
return return
@ -78,21 +78,21 @@ class ConnectionStrategy {
// use any resolved address // use any resolved address
if prefersResolvedAddresses, let resolvedAddress = anyResolvedAddress() { 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()) let socket = provider.createSocket(to: resolvedAddress, protocol: currentProtocol())
completionHandler(socket, nil) completionHandler(socket, nil)
return return
} }
// fall back to DNS // 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 DNSResolver.resolve(hostname, timeout: timeout, queue: queue) { (addresses, error) in
// refresh resolved addresses // refresh resolved addresses
if let resolved = addresses, !resolved.isEmpty { if let resolved = addresses, !resolved.isEmpty {
self.resolvedAddresses = resolved self.resolvedAddresses = resolved
log.debug("DNS resolved addresses: \(resolved)") log.debug("DNS resolved addresses: \(resolved.map { $0.maskedDescription })")
} else { } else {
log.error("DNS resolution failed!") log.error("DNS resolution failed!")
} }

View File

@ -75,7 +75,7 @@ class InterfaceObserver: NSObject {
let currentWifiName = currentWifiNetworkName() let currentWifiName = currentWifiNetworkName()
if (currentWifiName != lastWifiName) { if (currentWifiName != lastWifiName) {
if let current = currentWifiName { if let current = currentWifiName {
log.debug("SSID is now '\(current)'") log.debug("SSID is now '\(current.maskedDescription)'")
if let last = lastWifiName, (current != last) { if let last = lastWifiName, (current != last) {
queue?.async { queue?.async {
NotificationCenter.default.post(name: .__InterfaceObserverDidDetectWifiChange, object: nil) NotificationCenter.default.post(name: .__InterfaceObserverDidDetectWifiChange, object: nil)

View File

@ -137,9 +137,9 @@ class NETCPSocket: NSObject, GenericSocket {
switch keyPath { switch keyPath {
case #keyPath(NWTCPConnection.state): case #keyPath(NWTCPConnection.state):
if let resolvedEndpoint = impl.remoteAddress { 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 { } 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 { switch impl.state {
@ -250,8 +250,8 @@ class NETCPLink: LinkInterface {
extension NETCPSocket { extension NETCPSocket {
override var description: String { override var description: String {
guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else { 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)"
} }
} }

View File

@ -137,9 +137,9 @@ class NEUDPSocket: NSObject, GenericSocket {
switch keyPath { switch keyPath {
case #keyPath(NWUDPSession.state): case #keyPath(NWUDPSession.state):
if let resolvedEndpoint = impl.resolvedEndpoint { 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 { } 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 { switch impl.state {
@ -236,8 +236,8 @@ class NEUDPLink: LinkInterface {
extension NEUDPSocket { extension NEUDPSocket {
override var description: String { override var description: String {
guard let hostEndpoint = impl.endpoint as? NWHostEndpoint else { 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)"
} }
} }

View File

@ -527,7 +527,6 @@ extension TunnelKitProvider {
log.info("App version: \(appVersion)") log.info("App version: \(appVersion)")
} }
// log.info("\tAddress: \(endpoint.hostname):\(endpoint.port)")
log.info("\tProtocols: \(endpointProtocols)") log.info("\tProtocols: \(endpointProtocols)")
log.info("\tCipher: \(cipher)") log.info("\tCipher: \(cipher)")
log.info("\tDigest: \(digest)") log.info("\tDigest: \(digest)")

View File

@ -483,10 +483,10 @@ extension TunnelKitProvider: SessionProxyDelegate {
log.info("Session did start") log.info("Session did start")
log.info("Returned ifconfig parameters:") log.info("Returned ifconfig parameters:")
log.info("\tRemote: \(remoteAddress)") log.info("\tRemote: \(remoteAddress.maskedDescription)")
log.info("\tIPv4: \(reply.ipv4?.description ?? "not configured")") log.info("\tIPv4: \(reply.ipv4?.description ?? "not configured")")
log.info("\tIPv6: \(reply.ipv6?.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 bringNetworkUp(remoteAddress: remoteAddress, reply: reply) { (error) in
if let error = error { if let error = error {
@ -602,7 +602,7 @@ extension TunnelKitProvider {
private func logCurrentSSID() { private func logCurrentSSID() {
if let ssid = observer.currentWifiNetworkName() { if let ssid = observer.currentWifiNetworkName() {
log.debug("Current SSID: '\(ssid)'") log.debug("Current SSID: '\(ssid.maskedDescription)'")
} else { } else {
log.debug("Current SSID: none (disconnected from WiFi)") log.debug("Current SSID: none (disconnected from WiFi)")
} }

View File

@ -36,6 +36,7 @@
import Foundation import Foundation
import __TunnelKitNative import __TunnelKitNative
import CommonCrypto
struct CoreConfiguration { struct CoreConfiguration {
static let identifier = "com.algoritmico.TunnelKit" static let identifier = "com.algoritmico.TunnelKit"
@ -59,6 +60,8 @@ struct CoreConfiguration {
static let logsSensitiveData = false static let logsSensitiveData = false
static let masksPrivateData = true
static let usesReplayProtection = true static let usesReplayProtection = true
static let tickInterval = 0.2 static let tickInterval = 0.2
@ -97,3 +100,17 @@ struct CoreConfiguration {
static let keysCount = 4 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().prefix(16))#"
}
}

View File

@ -62,7 +62,7 @@ public struct IPv4Settings: CustomStringConvertible {
/// :nodoc: /// :nodoc:
public var description: String { 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: /// :nodoc:
public var description: String { 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: /// :nodoc:
public var description: String { 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: /// :nodoc:
public var description: String { 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 })"
} }
} }

View File

@ -856,7 +856,7 @@ public class SessionProxy {
return return
} }
reply = optionalReply reply = optionalReply
log.debug("Received PUSH_REPLY: \"\(reply)\"") log.debug("Received PUSH_REPLY: \"\(reply.maskedDescription)\"")
} catch let e { } catch let e {
deferStop(.shutdown, e) deferStop(.shutdown, e)
return return