Add provider configuration generation.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jeroen Leenarts 2018-08-06 09:04:29 +02:00
parent 2a0b84eeb9
commit 5697d6e7e2
3 changed files with 87 additions and 19 deletions

View File

@ -10,7 +10,90 @@ import Foundation
extension Tunnel {
public func generateProviderConfiguration() -> [String: Any] {
//TODO: generate ProviderConfiguration from tunnel with WireGuard config.
return [:]
var providerConfiguration = [String: Any]()
providerConfiguration["title"] = self.title
var settingsString = "replace_peers=true\n"
if let interface = interface {
settingsString += generateInterfaceProviderConfiguration(interface)
}
if let peers = peers?.array as? [Peer] {
peers.forEach {
settingsString += generatePeerProviderConfiguration($0)
}
}
providerConfiguration["settings"] = settingsString
return providerConfiguration
}
private func generateInterfaceProviderConfiguration(_ interface: Interface) -> String {
var settingsString = "replace_peers=true\n"
if let hexPrivateKey = base64KeyToHex(interface.privateKey) {
settingsString += "private_key=\(hexPrivateKey)\n"
}
if interface.listenPort > 0 {
settingsString += "listen_port=\(interface.listenPort)\n"
}
if let dns = interface.dns {
settingsString += "dns=\(dns)\n"
}
if interface.mtu > 0 {
settingsString += "mtu=\(interface.mtu)\n"
}
return settingsString
}
private func generatePeerProviderConfiguration(_ peer: Peer) -> String {
var settingsString = ""
if let hexPublicKey = base64KeyToHex(peer.publicKey) {
settingsString += "public_key=\(hexPublicKey)"
}
if let presharedKey = peer.presharedKey {
settingsString += "preshared_key=\(presharedKey)"
}
if let endpoint = peer.endpoint {
settingsString += "endpoint=\(endpoint)"
}
if peer.persistentKeepalive > 0 {
settingsString += "persistent_keepalive_interval=\(peer.persistentKeepalive)"
}
if let allowedIPs = peer.allowedIPs {
settingsString += "allowed_ip=\(allowedIPs)" // TODO: split on ,
}
return settingsString
}
}
private func base64KeyToHex(_ base64: String?) -> String? {
guard let base64 = base64 else {
return nil
}
guard base64.count == 44 else {
return nil
}
guard base64.last == "=" else {
return nil
}
guard let keyData = Data(base64Encoded: base64) else {
return nil
}
guard keyData.count == 32 else {
return nil
}
let hexKey = keyData.reduce("") {$0 + String(format: "%02x", $1)}
return hexKey
}

View File

@ -1,18 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14135" systemVersion="17E202" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Address" representedClassName="Address" syncable="YES">
<attribute name="address" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="interface" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Interface" inverseName="adresses" inverseEntity="Interface" syncable="YES"/>
</entity>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14135" systemVersion="17G65" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="Interface" representedClassName="Interface" syncable="YES">
<attribute name="dns" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="fwMark" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="listenPort" optional="YES" attributeType="Integer 16" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="mtu" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES" syncable="YES"/>
<attribute name="privateKey" attributeType="String" syncable="YES"/>
<attribute name="publicKey" attributeType="String" syncable="YES"/>
<attribute name="table" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="adresses" toMany="YES" deletionRule="Cascade" destinationEntity="Address" inverseName="interface" inverseEntity="Address" syncable="YES"/>
<relationship name="tunnel" maxCount="1" deletionRule="Nullify" destinationEntity="Tunnel" inverseName="interface" inverseEntity="Tunnel" syncable="YES"/>
</entity>
<entity name="Peer" representedClassName="Peer" syncable="YES">
@ -29,8 +21,7 @@
<relationship name="peers" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="Peer" inverseName="tunnel" inverseEntity="Peer" syncable="YES"/>
</entity>
<elements>
<element name="Address" positionX="-54" positionY="45" width="128" height="75"/>
<element name="Interface" positionX="-54" positionY="-9" width="128" height="180"/>
<element name="Interface" positionX="-54" positionY="-9" width="128" height="120"/>
<element name="Peer" positionX="-36" positionY="9" width="128" height="135"/>
<element name="Tunnel" positionX="160" positionY="192" width="128" height="90"/>
</elements>

View File

@ -21,12 +21,6 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
/// A reference to the WireGuard wrapper object.
let wireGuardWrapper = WireGuardGoWrapper()
/// The completion handler to call when the tunnel is fully established.
var pendingStartCompletion: ((Error?) -> Void)?
/// The completion handler to call when the tunnel is fully disconnected.
var pendingStopCompletion: (() -> Void)?
// MARK: NEPacketTunnelProvider
/// Begin the process of establishing the tunnel.