Initial, holiday fun

This commit is contained in:
Ryan McGrath 2018-12-26 18:34:03 -08:00
commit abcab0c509
No known key found for this signature in database
GPG key ID: 811674B62B666830
18 changed files with 2638 additions and 0 deletions

103
four/VPNManager.swift Normal file
View file

@ -0,0 +1,103 @@
//
// VPNManager.swift
// four
//
// Created by Ryan McGrath on 12/24/18.
// Copyright © 2018 Ryan McGrath. All rights reserved.
//
import Foundation
import NetworkExtension
class VPNManager {
fileprivate var manager = NETunnelProviderManager()
fileprivate static let vpnDescription = "CloudFlare 1.1.1.1 DNS"
fileprivate static let vpnServerDescription = "CloudFlare 1.1.1.1 DNS"
fileprivate static let vpnDNS = ["1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001"]
public var connected: Bool {
get {
return manager.isOnDemandEnabled
}
set {
if newValue == connected { return }
update(body: { [weak self] in
self?.manager.isEnabled = newValue
self?.manager.isOnDemandEnabled = newValue
}, complete: { [weak self] in
let session = self?.manager.connection as? NETunnelProviderSession
if newValue {
do {
try session?.startVPNTunnel(options: nil)
print("STARTED!")
} catch let err as NSError {
print("\(err.localizedDescription)")
}
} else {
session?.stopVPNTunnel()
}
})
}
}
init() {
refreshManager()
}
func refreshManager() -> Void {
NETunnelProviderManager.loadAllFromPreferences(completionHandler: { (managers, error) in
if nil == error {
if let managers = managers {
for manager in managers {
if manager.localizedDescription == VPNManager.vpnDescription {
self.manager = manager
return
}
}
}
}
self.configureDNS()
})
}
private func update(body: @escaping () -> Void, complete: @escaping () -> Void) {
manager.loadFromPreferences { error in
if error != nil {
print("Load error: \(String(describing: error?.localizedDescription))")
return
}
body()
self.manager.saveToPreferences { (error) in
if nil != error {
print("vpn_connect: save error \(error!)")
} else {
complete()
}
}
}
}
private func configureDNS() {
manager.localizedDescription = VPNManager.vpnDescription
let proto = NETunnelProviderProtocol()
proto.providerBundleIdentifier = "com.rymc.vpntunnel.provider"
proto.serverAddress = VPNManager.vpnServerDescription
manager.protocolConfiguration = proto
let evaluationRule = NEEvaluateConnectionRule(matchDomains: TLDS, andAction: .connectIfNeeded)
evaluationRule.useDNSServers = VPNManager.vpnDNS
let onDemandRule = NEOnDemandRuleEvaluateConnection()
onDemandRule.connectionRules = [evaluationRule]
onDemandRule.interfaceTypeMatch = .any
manager.onDemandRules = [onDemandRule]
}
}