Skip to content

Commit

Permalink
Merge pull request #5 from pia-foss/PIA-1878-Capture-DNS-request-of-a…
Browse files Browse the repository at this point in the history
…-managed-app

Pia 1878 capture dns request of a managed app
  • Loading branch information
kp-michele-emiliani authored Jun 19, 2024
2 parents 420f243 + b9b5987 commit 00cfea5
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 17 deletions.
3 changes: 1 addition & 2 deletions ProxyApp/ProxyAppDefault.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ class ProxyAppDefault : ProxyApp {
"logLevel" : "debug",
"routeVpn" : true,
"isConnected" : true,
// The name of the unix group pia whitelists in the firewall
// This may be different when PIA is white-labeled
// The name of the unix group PIA whitelists in the firewall
"whitelistGroupName" : "piavpn"
] as [String : Any])
} catch {
Expand Down
13 changes: 6 additions & 7 deletions ProxyApp/ProxyAppGUI.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
/**
This is the main of the ProxyApp GUI client, the extension graphical client.
This is a viable way of managing the system extension,
but it's only used during development work.
This is the main of the ProxyApp GUI client, a graphical client for the extension process.
This is a viable way of managing the system extension.
Right now, it's only used during development work.

This GUI is not shipped with PIA desktop client.
The integrated project communicate with the extension
using only the cli client ProxyCLI.
Both share the same functionalities.
This GUI is not shipped with PIA desktop client,
which uses the cli client ProxyCLI.
Both the gui and the cli client share the same functionalities.
*/

import SwiftUI
Expand Down
4 changes: 3 additions & 1 deletion ProxyExtension/IO/FlowHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct SessionConfig {

protocol FlowHandlerProtocol {
func handleNewFlow(_ flow: Flow, vpnState: VpnState) -> Bool
func startProxySession(flow: Flow, vpnState: VpnState) -> Bool
}

// Responsible for handling flows, both new flows and pre-existing
Expand Down Expand Up @@ -50,7 +51,8 @@ final class FlowHandler: FlowHandlerProtocol {
}
}

private func startProxySession(flow: Flow, vpnState: VpnState) -> Bool {
// temporarly public
public func startProxySession(flow: Flow, vpnState: VpnState) -> Bool {
let interface = networkInterfaceFactory.create(interfaceName: vpnState.bindInterface)

// Verify we have a valid bindIp - if not, trace it and ignore the flow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,62 @@ import Foundation
import NetworkExtension

final class SplitTunnelDNSProxyProvider : NEDNSProxyProvider {
override init() {
super.init()
}


public var flowHandler: FlowHandlerProtocol!
public var vpnState: VpnState!

// The logger
public var logger: LoggerProtocol!

override func startProxy(options:[String: Any]? = nil, completionHandler: @escaping (Error?) -> Void) {
let logLevel: String = options?["logLevel"] as? String ?? ""
let logFile: String = options?["logFile"] as? String ?? ""

self.logger = self.logger ?? Logger.instance

// Ensure the logger is initialized first
logger.updateLogger(logLevel: logLevel, logFile: logFile)

// init just once, set up swiftNIO event loop
self.flowHandler = FlowHandler()

var options = [
"bypassApps" : ["/usr/bin/curl", "org.mozilla.firefox"],
"vpnOnlyApps" : [],
"bindInterface" : "en0",
"serverAddress" : "127.0.0.1",
"logFile" : "/tmp/STProxy.log",
"logLevel" : "debug",
"routeVpn" : true,
"isConnected" : true,
"whitelistGroupName" : "piavpn"
] as [String : Any]
guard let vpnState2 = VpnStateFactory.create(options: options) else {
log(.error, "provided incorrect list of options. They might be missing or an incorrect type")
return
}
vpnState = vpnState2

completionHandler(nil)
}

override func stopProxy(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
completionHandler()
}

// Be aware that by returning false in NEDNSProxyProvider handleNewFlow(),
// the flow is discarded and the connection is closed
// Be aware that by returning false in NEDNSProxyProvider handleNewFlow(),
// the flow is discarded and the connection is closed.
// This is similar to how NEAppProxyProvider works, compared to what we use
// for traffic Split Tunnel which is NETransparentProxyProvider.
// This means that we need to handle ALL DNS requests when DNS Split Tunnel
// is enabled, even for non-managed apps.
override func handleNewFlow(_ flow: NEAppProxyFlow) -> Bool {
return false
var appName = flow.sourceAppSigningIdentifier
if appName == "com.apple.nslookup" || appName == "com.apple.curl" {
flowHandler.startProxySession(flow: flow, vpnState: vpnState)
return true
} else {
return false
}
}
}
5 changes: 5 additions & 0 deletions ProxyTests/Mocks/MockFlowHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ final class MockFlowHandler: FlowHandlerProtocol, Mock {
record(args: [flow, vpnState])
return true
}

func startProxySession(flow: Flow, vpnState: VpnState) -> Bool {
record(args: [flow, vpnState])
return true
}
}

0 comments on commit 00cfea5

Please sign in to comment.