diff --git a/WireGuard/AppDelegate.swift b/WireGuard/AppDelegate.swift
deleted file mode 100644
index 6380636..0000000
--- a/WireGuard/AppDelegate.swift
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-import os.log
-
-@UIApplicationMain
-class AppDelegate: UIResponder, UIApplicationDelegate {
-
- var window: UIWindow?
- var appCoordinator: AppCoordinator!
-
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
-
- self.window = UIWindow(frame: UIScreen.main.bounds)
- appCoordinator = AppCoordinator(window: self.window!)
- appCoordinator.start()
-
- appCoordinator.checkAndCleanConfigs()
-
- return true
- }
-
- func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
- defer {
- do {
- try FileManager.default.removeItem(at: url)
- } catch {
- os_log("Failed to remove item from Inbox: %{public}@", log: Log.general, type: .error, url.absoluteString)
- }
- }
- if url.pathExtension == "conf" {
- do {
- try appCoordinator.importConfig(config: url)
- } catch {
- os_log("Unable to import config: %{public}@", log: Log.general, type: .error, url.absoluteString)
- return false
- }
- return true
- } else if url.pathExtension == "zip" {
- do {
- try appCoordinator.importConfigs(configZip: url)
- } catch {
- os_log("Unable to import config: %{public}@", log: Log.general, type: .error, url.absoluteString)
- return false
- }
- return true
- }
- return false
-
- }
-
- func applicationWillEnterForeground(_ application: UIApplication) {
- appCoordinator.checkAndCleanConfigs()
- }
-}
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/Contents.json b/WireGuard/Assets.xcassets/AppIcon.appiconset/Contents.json
deleted file mode 100644
index 29d9125..0000000
--- a/WireGuard/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ /dev/null
@@ -1,116 +0,0 @@
-{
- "images" : [
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "icon_20pt@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "icon_20pt@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "icon_29pt@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "icon_29pt@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "icon_40pt@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "icon_40pt@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "icon_60pt@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "icon_60pt@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "icon_20pt.png",
- "scale" : "1x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "icon_20pt@2x-1.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "icon_29pt.png",
- "scale" : "1x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "icon_29pt@2x-1.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "icon_40pt.png",
- "scale" : "1x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "icon_40pt@2x-1.png",
- "scale" : "2x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "icon_76pt.png",
- "scale" : "1x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "icon_76pt@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "83.5x83.5",
- "idiom" : "ipad",
- "filename" : "icon_83.5@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "1024x1024",
- "idiom" : "ios-marketing",
- "filename" : "Icon.png",
- "scale" : "1x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/Icon.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/Icon.png
deleted file mode 100644
index 7b0779f..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/Icon.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt.png
deleted file mode 100644
index d12a297..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png
deleted file mode 100644
index 7f1668d..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png
deleted file mode 100644
index 7f1668d..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png
deleted file mode 100644
index 28c67d4..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt.png
deleted file mode 100644
index 8ec8d93..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png
deleted file mode 100644
index a7739f5..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png
deleted file mode 100644
index ed8332f..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png
deleted file mode 100644
index e436f81..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt.png
deleted file mode 100644
index 7f1668d..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png
deleted file mode 100644
index d0e7d2c..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png
deleted file mode 100644
index bc73ca8..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png
deleted file mode 100644
index 410f082..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png
deleted file mode 100644
index 410f082..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png
deleted file mode 100644
index 4c799aa..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_76pt.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_76pt.png
deleted file mode 100644
index 0565869..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_76pt.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png
deleted file mode 100644
index 8c378fd..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png b/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png
deleted file mode 100644
index f575275..0000000
Binary files a/WireGuard/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/Arrow.imageset/Arrow.pdf b/WireGuard/Assets.xcassets/Arrow.imageset/Arrow.pdf
deleted file mode 100644
index 781e309..0000000
Binary files a/WireGuard/Assets.xcassets/Arrow.imageset/Arrow.pdf and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/Arrow.imageset/Contents.json b/WireGuard/Assets.xcassets/Arrow.imageset/Contents.json
deleted file mode 100644
index 77459c6..0000000
--- a/WireGuard/Assets.xcassets/Arrow.imageset/Contents.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "Arrow.pdf"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- },
- "properties" : {
- "preserves-vector-representation" : true
- }
-}
\ No newline at end of file
diff --git a/WireGuard/Assets.xcassets/Contents.json b/WireGuard/Assets.xcassets/Contents.json
deleted file mode 100644
index da4a164..0000000
--- a/WireGuard/Assets.xcassets/Contents.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/WireGuard/Assets.xcassets/settings.imageset/Contents.json b/WireGuard/Assets.xcassets/settings.imageset/Contents.json
deleted file mode 100644
index ab3fbb2..0000000
--- a/WireGuard/Assets.xcassets/settings.imageset/Contents.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "Dots.pdf"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- },
- "properties" : {
- "preserves-vector-representation" : true
- }
-}
\ No newline at end of file
diff --git a/WireGuard/Assets.xcassets/settings.imageset/Dots.pdf b/WireGuard/Assets.xcassets/settings.imageset/Dots.pdf
deleted file mode 100644
index c5a2168..0000000
Binary files a/WireGuard/Assets.xcassets/settings.imageset/Dots.pdf and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/trash.imageset/Contents.json b/WireGuard/Assets.xcassets/trash.imageset/Contents.json
deleted file mode 100644
index af5374f..0000000
--- a/WireGuard/Assets.xcassets/trash.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "ic_action_delete.png",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "ic_action_delete@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "filename" : "ic_action_delete@3x.png",
- "scale" : "3x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete.png b/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete.png
deleted file mode 100644
index de3dd1c..0000000
Binary files a/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete@2x.png b/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete@2x.png
deleted file mode 100644
index e542a9b..0000000
Binary files a/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete@2x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete@3x.png b/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete@3x.png
deleted file mode 100644
index 1b6b07c..0000000
Binary files a/WireGuard/Assets.xcassets/trash.imageset/ic_action_delete@3x.png and /dev/null differ
diff --git a/WireGuard/Assets.xcassets/wireguard.imageset/Contents.json b/WireGuard/Assets.xcassets/wireguard.imageset/Contents.json
deleted file mode 100644
index 6c935c1..0000000
--- a/WireGuard/Assets.xcassets/wireguard.imageset/Contents.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "wireguard.pdf"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- },
- "properties" : {
- "preserves-vector-representation" : true
- }
-}
\ No newline at end of file
diff --git a/WireGuard/Assets.xcassets/wireguard.imageset/wireguard.pdf b/WireGuard/Assets.xcassets/wireguard.imageset/wireguard.pdf
deleted file mode 100644
index f404859..0000000
Binary files a/WireGuard/Assets.xcassets/wireguard.imageset/wireguard.pdf and /dev/null differ
diff --git a/WireGuard/Base.lproj/LaunchScreen.storyboard b/WireGuard/Base.lproj/LaunchScreen.storyboard
deleted file mode 100644
index 4b77684..0000000
--- a/WireGuard/Base.lproj/LaunchScreen.storyboard
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/WireGuard/Base.lproj/Main.storyboard b/WireGuard/Base.lproj/Main.storyboard
deleted file mode 100644
index c9ae86c..0000000
--- a/WireGuard/Base.lproj/Main.storyboard
+++ /dev/null
@@ -1,1010 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/WireGuard/Coordinators/AppCoordinator+QRScanViewControllerDelegate.swift b/WireGuard/Coordinators/AppCoordinator+QRScanViewControllerDelegate.swift
deleted file mode 100644
index d76470b..0000000
--- a/WireGuard/Coordinators/AppCoordinator+QRScanViewControllerDelegate.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-extension AppCoordinator: QRScanViewControllerDelegate {
- func didSave(tunnel: Tunnel, qrScanViewController: QRScanViewController) {
- qrScanViewController.navigationController?.popViewController(animated: true)
- showTunnelInfoViewController(tunnel: tunnel, context: tunnel.managedObjectContext!)
- saveTunnel(tunnel)
- }
-
- func didCancel(qrScanViewController: QRScanViewController) {
- qrScanViewController.navigationController?.popViewController(animated: true)
- }
-}
diff --git a/WireGuard/Coordinators/AppCoordinator+SettingsTableViewControllerDelegate.swift b/WireGuard/Coordinators/AppCoordinator+SettingsTableViewControllerDelegate.swift
deleted file mode 100644
index 9961043..0000000
--- a/WireGuard/Coordinators/AppCoordinator+SettingsTableViewControllerDelegate.swift
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-import PromiseKit
-import NetworkExtension
-
-enum GoVersionCoordinatorError: Error {
- case noEnabledSession
- case noResponse
-}
-
-extension AppCoordinator: SettingsTableViewControllerDelegate {
- func exportTunnels(settingsTableViewController: SettingsTableViewController, sourceView: UIView) {
- self.exportConfigs(sourceView: sourceView)
- }
-}
diff --git a/WireGuard/Coordinators/AppCoordinator+TunnelConfigurationTableViewControllerDelegate.swift b/WireGuard/Coordinators/AppCoordinator+TunnelConfigurationTableViewControllerDelegate.swift
deleted file mode 100644
index 0b96762..0000000
--- a/WireGuard/Coordinators/AppCoordinator+TunnelConfigurationTableViewControllerDelegate.swift
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-extension AppCoordinator: TunnelConfigurationTableViewControllerDelegate {
- func didSave(tunnel: Tunnel, tunnelConfigurationTableViewController: TunnelConfigurationTableViewController) {
- saveTunnel(tunnel)
- }
-}
diff --git a/WireGuard/Coordinators/AppCoordinator+TunnelInfoTableViewControllerDelegate.swift b/WireGuard/Coordinators/AppCoordinator+TunnelInfoTableViewControllerDelegate.swift
deleted file mode 100644
index aa6f3f2..0000000
--- a/WireGuard/Coordinators/AppCoordinator+TunnelInfoTableViewControllerDelegate.swift
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import NetworkExtension
-
-extension AppCoordinator: TunnelInfoTableViewControllerDelegate {
- func connect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
- connect(tunnel: tunnel)
- }
-
- func disconnect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
- disconnect(tunnel: tunnel)
- }
-
- func status(for tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) -> NEVPNStatus {
- let session = self.providerManager(for: tunnel)?.connection as? NETunnelProviderSession
- return session?.status ?? .invalid
- }
-
- func configure(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
- let editContext = persistentContainer.newBackgroundContext()
- var backgroundTunnel: Tunnel?
- editContext.performAndWait {
- backgroundTunnel = editContext.object(with: tunnel.objectID) as? Tunnel
- }
-
- showTunnelConfigurationViewController(tunnel: backgroundTunnel, context: editContext)
- }
-
-}
diff --git a/WireGuard/Coordinators/AppCoordinator+TunnelsTableViewControllerDelegate.swift b/WireGuard/Coordinators/AppCoordinator+TunnelsTableViewControllerDelegate.swift
deleted file mode 100644
index 0357c40..0000000
--- a/WireGuard/Coordinators/AppCoordinator+TunnelsTableViewControllerDelegate.swift
+++ /dev/null
@@ -1,114 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-import NetworkExtension
-import os.log
-
-import MobileCoreServices
-
-import ZIPFoundation
-import PromiseKit
-
-extension AppCoordinator: TunnelsTableViewControllerDelegate {
- func status(for tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) -> NEVPNStatus {
- let session = self.providerManager(for: tunnel)?.connection as? NETunnelProviderSession
- return session?.status ?? .invalid
- }
-
- func addProvider(tunnelsTableViewController: TunnelsTableViewController) {
- let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
- actionSheet.addAction(UIAlertAction(title: NSLocalizedString("Create from file or archive", comment: ""), style: .default) { [unowned self] _ in
- self.addProviderFromFile()
- })
- actionSheet.addAction(UIAlertAction(title: NSLocalizedString("Create from QR code", comment: ""), style: .default) { [unowned self] _ in
- self.addProviderWithQRScan()
- })
- actionSheet.addAction(UIAlertAction(title: NSLocalizedString("Create from scratch", comment: ""), style: .default) { [unowned self] _ in
- self.addProviderManually()
- })
- actionSheet.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel))
-
- tunnelsTableViewController.present(actionSheet, animated: true, completion: nil)
- }
-
- func addProviderFromFile() {
- let documentPickerController = UIDocumentPickerViewController(documentTypes: [String(kUTTypeZipArchive), "com.wireguard.config.quick"], in: .import)
- documentPickerController.delegate = documentPickerDelegateObject
- tunnelsTableViewController.present(documentPickerController, animated: true, completion: nil)
- }
-
- func addProviderManually() {
- let addContext = persistentContainer.newBackgroundContext()
- showTunnelConfigurationViewController(tunnel: nil, context: addContext)
- }
-
- func addProviderWithQRScan() {
- let addContext = persistentContainer.newBackgroundContext()
-
- let qrScanViewController = storyboard.instantiateViewController(type: QRScanViewController.self)
-
- qrScanViewController.configure(context: addContext, delegate: self)
-
- self.navigationController.pushViewController(qrScanViewController, animated: true)
- }
-
- func connect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
- connect(tunnel: tunnel)
- }
-
- func disconnect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
- disconnect(tunnel: tunnel)
- }
-
- func info(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
- showTunnelInfoViewController(tunnel: tunnel, context: self.persistentContainer.viewContext)
- }
-
- func delete(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
- if let moc = tunnel.managedObjectContext {
- moc.perform {
- moc.delete(tunnel)
- moc.saveContextToStore()
- }
- let manager = providerManager(for: tunnel)
- manager?.removeFromPreferences { (error) in
- if let error = error {
- os_log("error removing preferences: %{public}@", log: Log.general, type: .error, error.localizedDescription)
- return
- }
- self.providerManagers?.removeAll { $0 == manager }
- os_log("removed preferences", log: Log.general, type: .info)
- }
- }
- }
-
- func saveTunnel(_ tunnel: Tunnel) {
- let manager = providerManager(for: tunnel) ?? NETunnelProviderManager()
- manager.localizedDescription = tunnel.title
-
- let protocolConfiguration = NETunnelProviderProtocol()
- protocolConfiguration.providerBundleIdentifier = VPNBUNDLE
- protocolConfiguration.serverAddress = (tunnel.peers?.array as? [Peer])?.compactMap { $0.endpoint}.joined(separator: ", ")
- protocolConfiguration.providerConfiguration = tunnel.generateProviderConfiguration()
-
- manager.protocolConfiguration = protocolConfiguration
- let connectRule = NEOnDemandRuleConnect()
- connectRule.interfaceTypeMatch = .any
- manager.onDemandRules = [connectRule]
-
- manager.saveToPreferences { (error) in
- if let error = error {
- os_log("error saving preferences: %{public}@", log: Log.general, type: .error, error.localizedDescription)
- return
- }
- os_log("saved preferences", log: Log.general, type: .info)
- }
-
- _ = refreshProviderManagers().then { () -> Promise in
- self.navigationController.popViewController(animated: true)
- return Promise.value(())
- }
- }
-}
diff --git a/WireGuard/Coordinators/AppCoordinator.swift b/WireGuard/Coordinators/AppCoordinator.swift
deleted file mode 100644
index aa20c16..0000000
--- a/WireGuard/Coordinators/AppCoordinator.swift
+++ /dev/null
@@ -1,468 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import NetworkExtension
-import os.log
-import ZIPFoundation
-import PromiseKit
-
-import CoreData
-import BNRCoreDataStack
-
-import MobileCoreServices
-
-enum AppCoordinatorError: Error {
- case configImportError(msg: String)
-}
-
-extension UINavigationController: Identifyable {}
-
-let APPGROUP = "group.com.wireguard.ios"
-let VPNBUNDLE = "com.wireguard.ios.network-extension"
-
-class AppCoordinator: RootViewCoordinator { // swiftlint:disable:this type_body_length
-
- let persistentContainer = NSPersistentContainer(name: "WireGuard")
- let storyboard = UIStoryboard(name: "Main", bundle: nil)
- var providerManagers: [NETunnelProviderManager]?
- let documentPickerDelegateObject: AppDocumentPickerDelegate
-
- // MARK: - Properties
-
- var childCoordinators: [Coordinator] = []
-
- var rootViewController: UIViewController {
- return self.tunnelsTableViewController
- }
-
- var tunnelsTableViewController: TunnelsTableViewController!
-
- /// Window to manage
- let window: UIWindow
-
- let navigationController: UINavigationController = {
- let navController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(type: UINavigationController.self)
- return navController
- }()
-
- // MARK: - Init
- public init(window: UIWindow) {
- self.window = window
-
- self.window.rootViewController = self.navigationController
- self.window.makeKeyAndVisible()
-
- documentPickerDelegateObject = AppDocumentPickerDelegate()
- documentPickerDelegateObject.appCoordinator = self
-
- NotificationCenter.default.addObserver(self,
- selector: #selector(VPNStatusDidChange(notification:)),
- name: .NEVPNStatusDidChange,
- object: nil)
- }
-
- // MARK: - Functions
-
- /// Starts the coordinator
- public func start() {
- _ = refreshProviderManagers().then { () -> Promise in
- self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
- self.persistentContainer.loadPersistentStores { [weak self] (_, error) in
- if let error = error {
- os_log("Unable to load Persistent Store: %{public}@", log: Log.general, type: .error, error.localizedDescription)
- } else {
- DispatchQueue.main.async {
- //start
- if let tunnelsTableViewController = self?.storyboard.instantiateViewController(type: TunnelsTableViewController.self) {
- self?.tunnelsTableViewController = tunnelsTableViewController
- self?.tunnelsTableViewController.viewContext = self?.persistentContainer.viewContext
- self?.tunnelsTableViewController.delegate = self
- self?.navigationController.viewControllers = [tunnelsTableViewController]
- }
- }
- }
- }
- return Promise.value(())
- }
- }
-
- func refreshProviderManagers() -> Promise {
- return Promise { (resolver) in
- NETunnelProviderManager.loadAllFromPreferences { [weak self] (managers, error) in
- if let error = error {
- os_log("Unable to load provider managers: %{public}@", log: Log.general, type: .error, error.localizedDescription)
- }
- self?.providerManagers = managers
- resolver.fulfill(())
- }
- }
- }
-
- func importConfig(config: URL) throws {
- do {
- try importConfig(configString: try String(contentsOf: config), title: config.deletingPathExtension().lastPathComponent)
- } catch {
- throw AppCoordinatorError.configImportError(msg: "Failed")
- }
- }
-
- func importConfig(configString: String, title: String) throws {
- do {
- let addContext = persistentContainer.newBackgroundContext()
- let tunnel = try Tunnel.fromConfig(configString, context: addContext)
- tunnel.title = title
- addContext.saveContext()
- self.saveTunnel(tunnel)
- } catch {
- throw AppCoordinatorError.configImportError(msg: "Failed")
- }
- }
-
- func importConfigs(configZip: URL) throws {
- if let archive = Archive(url: configZip, accessMode: .read) {
- for entry in archive {
- var entryData = Data(capacity: 0)
- _ = try archive.extract(entry) { (data) in
- entryData.append(data)
- }
- if let config = String(data: entryData, encoding: .utf8) {
- try importConfig(configString: config, title: entry.path)
- }
- }
- }
- }
-
- func checkAndCleanConfigs() {
- _ = refreshProviderManagers().then { () -> Promise in
- guard let providerManagers = self.providerManagers else {
- return Promise.value(())
- }
- let tunnels = try Tunnel.allInContext(self.persistentContainer.viewContext)
- let tunnelIdentifiers = tunnels.compactMap {$0.tunnelIdentifier}
-
- let unknownManagers = providerManagers.filter {
- guard let prot = $0.protocolConfiguration as? NETunnelProviderProtocol else {
- return false
- }
- guard let candidateTunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
- return false
- }
-
- return !tunnelIdentifiers.contains(candidateTunnelIdentifier)
- }
-
- let deletionPromises = unknownManagers.map({ (manager) -> Promise in
- return Promise(resolver: { resolver in
- return manager.removeFromPreferences(completionHandler: { (error) in
- if let error = error {
- resolver.reject(error)
- } else {
- resolver.fulfill(manager)
- }
- })
- })
- })
-
- return when(resolved: deletionPromises).asVoid()
-
- }
- }
-
- // swiftlint:disable next function_body_length
- func exportConfigs(sourceView: UIView) {
- guard let path = FileManager.default
- .urls(for: .documentDirectory, in: .userDomainMask).first else {
- return
- }
- let saveFileURL = path.appendingPathComponent("wireguard-export.zip")
- do {
- try FileManager.default.removeItem(at: saveFileURL)
- } catch {
- os_log("Failed to delete file: %{public}@ : %{public}@", log: Log.general, type: .error, saveFileURL.absoluteString, error.localizedDescription)
- }
-
- guard let archive = Archive(url: saveFileURL, accessMode: .create) else {
- return
- }
-
- do {
- var tunnelsByTitle = [String: [Tunnel]]()
- let tunnels = try Tunnel.allInContext(persistentContainer.viewContext)
- tunnels.forEach {
- guard let title = $0.title ?? $0.tunnelIdentifier else {
- // there is always a tunnelidentifier.
- return
- }
- if let tunnels = tunnelsByTitle[title] {
- tunnelsByTitle[title] = tunnels + [$0]
- } else {
- tunnelsByTitle[title] = [$0]
- }
- }
-
- func addEntry(title: String, tunnel: Tunnel) throws {
- let data = tunnel.export().data(using: .utf8)!
- let byteCount: UInt32 = UInt32(data.count)
- try archive.addEntry(with: "\(title).conf", type: .file, uncompressedSize: byteCount, provider: { (position, size) -> Data in
- return data.subdata(in: position ..< size)
- })
- }
-
- try tunnelsByTitle.keys.forEach {
- if let tunnels = tunnelsByTitle[$0] {
- if tunnels.count == 1 {
- try addEntry(title: $0, tunnel: tunnels[0])
- } else {
- for (index, tunnel) in tunnels.enumerated() {
- try addEntry(title: $0 + "-\(index + 1)", tunnel: tunnel)
- }
- }
- }
- }
- } catch {
- os_log("Failed to create archive file: %{public}@ : %{public}@", log: Log.general, type: .error, saveFileURL.absoluteString, error.localizedDescription)
- return
- }
-
- let activityViewController = UIActivityViewController(
- activityItems: [saveFileURL],
- applicationActivities: nil)
- if let popoverPresentationController = activityViewController.popoverPresentationController {
- popoverPresentationController.sourceView = sourceView
- }
- navigationController.present(activityViewController, animated: true) {
- }
- }
-
- func exportConfig(tunnel: Tunnel, barButtonItem: UIBarButtonItem) {
- let exportString = tunnel.export()
-
- guard let path = FileManager.default
- .urls(for: .documentDirectory, in: .userDomainMask).first else {
- return
- }
- let saveFileURL = path.appendingPathComponent("/\(tunnel.title ?? "wireguard").conf")
- do {
- try exportString.write(to: saveFileURL, atomically: true, encoding: .utf8)
- } catch {
- os_log("Failed to export tunnel to: %{public}@", log: Log.general, type: .error, saveFileURL.absoluteString)
- return
- }
-
- let activityViewController = UIActivityViewController(
- activityItems: [saveFileURL],
- applicationActivities: nil)
- if let popoverPresentationController = activityViewController.popoverPresentationController {
- popoverPresentationController.barButtonItem = barButtonItem
- }
- self.navigationController.present(activityViewController, animated: true) {
- }
- }
-
- // MARK: - NEVPNManager handling
-
- @objc private func VPNStatusDidChange(notification: NSNotification) {
- guard let session = notification.object as? NETunnelProviderSession else {
- return
- }
-
- guard let prot = session.manager.protocolConfiguration as? NETunnelProviderProtocol else {
- return
- }
-
- guard let changedTunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
- return
- }
-
- providerManagers?.first(where: { (manager) -> Bool in
- guard let prot = manager.protocolConfiguration as? NETunnelProviderProtocol else {
- return false
- }
- guard let candidateTunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
- return false
- }
-
- return changedTunnelIdentifier == candidateTunnelIdentifier
-
- })?.loadFromPreferences(completionHandler: { [weak self] (_) in
- self?.tunnelsTableViewController.updateStatus(for: changedTunnelIdentifier)
- })
- }
-
- func showTunnelInfoViewController(tunnel: Tunnel, context: NSManagedObjectContext) {
- let tunnelInfoViewController = storyboard.instantiateViewController(type: TunnelInfoTableViewController.self)
-
- tunnelInfoViewController.configure(context: context, delegate: self, tunnel: tunnel)
-
- self.navigationController.pushViewController(tunnelInfoViewController, animated: true)
- }
-
- func showTunnelConfigurationViewController(tunnel: Tunnel?, context: NSManagedObjectContext) {
- let tunnelConfigurationViewController = storyboard.instantiateViewController(type: TunnelConfigurationTableViewController.self)
-
- tunnelConfigurationViewController.configure(context: context, delegate: self, tunnel: tunnel)
-
- self.navigationController.pushViewController(tunnelConfigurationViewController, animated: true)
- }
-
- func showSettings() {
- let settingsTableViewController = storyboard.instantiateViewController(type: SettingsTableViewController.self)
-
- settingsTableViewController.delegate = self
-
- self.navigationController.pushViewController(settingsTableViewController, animated: true)
- }
-
- public func showError(_ error: Error) {
- showAlert(title: NSLocalizedString("Error", comment: "Error alert title"), message: error.localizedDescription)
- }
-
- func connect(tunnel: Tunnel) {
- _ = refreshProviderManagers().then { () -> Promise in
- guard let manager = self.providerManager(for: tunnel) else {
- return Promise.value(())
- }
- let block = {
- switch manager.connection.status {
- case .invalid, .disconnected:
- os_log("connect tunnel: %{public}@", log: Log.general, type: .info, tunnel.description)
- // Should the manager be enabled?
-
- let manager = self.providerManager(for: tunnel)
- manager?.isEnabled = true
- manager?.saveToPreferences { (error) in
- if let error = error {
- os_log("error saving preferences: %{public}@", log: Log.general, type: .error, error.localizedDescription)
- return
- }
- os_log("saved preferences", log: Log.general, type: .info)
-
- let session = manager?.connection as! NETunnelProviderSession //swiftlint:disable:this force_cast
- do {
- try session.startTunnel()
- } catch let error {
- os_log("error starting tunnel: %{public}@", log: Log.general, type: .error, error.localizedDescription)
- }
- }
-
- default:
- break
- }
- }
-
- if manager.connection.status == .invalid {
- manager.loadFromPreferences { (_) in
- block()
- }
- } else {
- block()
- }
-
- return Promise.value(())
- }
- }
-
- func disconnect(tunnel: Tunnel) {
- _ = refreshProviderManagers().then { () -> Promise in
- let manager = self.providerManager(for: tunnel)!
- let block = {
- switch manager.connection.status {
- case .connected, .connecting:
- let manager = self.providerManager(for: tunnel)
- manager?.connection.stopVPNTunnel()
- default:
- break
- }
- }
-
- if manager.connection.status == .invalid {
- manager.loadFromPreferences { (_) in
- block()
- }
- } else {
- block()
- }
- return Promise.value(())
- }
- }
-
- private func showAlert(title: String, message: String) {
- let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
- alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default))
- self.navigationController.present(alert, animated: true)
- }
-
- func providerManager(for tunnel: Tunnel) -> NETunnelProviderManager? {
- return self.providerManagers?.first {
- guard let prot = $0.protocolConfiguration as? NETunnelProviderProtocol else {
- return false
- }
- guard let tunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
- return false
- }
- return tunnelIdentifier == tunnel.tunnelIdentifier
- }
- }
-
- func extensionGoVersionInformation() -> Promise {
- return Promise(resolver: { (resolver) in
- guard let session = self.providerManagers?.first(where: { $0.isEnabled })?.connection as? NETunnelProviderSession else {
- resolver.reject(GoVersionCoordinatorError.noEnabledSession)
- return
- }
- do {
- try session.sendProviderMessage(ExtensionMessage.requestVersion.data, responseHandler: { (data) in
- guard let data = data, let responseString = String(data: data, encoding: .utf8) else {
- resolver.reject(GoVersionCoordinatorError.noResponse)
- return
- }
- resolver.fulfill(responseString)
- })
- } catch {
- resolver.reject(error)
- }
- })
- }
-}
-
-class AppDocumentPickerDelegate: NSObject, UIDocumentPickerDelegate {
- weak var appCoordinator: AppCoordinator?
-
- func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
- if url.pathExtension == "conf" {
- do {
- try appCoordinator?.importConfig(config: url)
- } catch {
- os_log("Unable to import config: %{public}@", log: Log.general, type: .error, url.absoluteString)
- }
- } else if url.pathExtension == "zip" {
- do {
- try appCoordinator?.importConfigs(configZip: url)
- } catch {
- os_log("Unable to import config: %{public}@", log: Log.general, type: .error, url.absoluteString)
- }
- }
-
- }
-}
-
-extension NEVPNStatus {
- var statusDescription: String {
- switch self {
- case .connected:
- return "Connected"
- case .connecting:
- return "Connecting"
- case .disconnected:
- return "Disconnected"
- case .disconnecting:
- return "Disconnecting"
- case .invalid:
- return "Invalid"
- case .reasserting:
- return "Reasserting"
- }
- }
-}
diff --git a/WireGuard/Coordinators/Coordinator.swift b/WireGuard/Coordinators/Coordinator.swift
deleted file mode 100644
index d4263fc..0000000
--- a/WireGuard/Coordinators/Coordinator.swift
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-/// The Coordinator protocol
-public protocol Coordinator: class {
-
- /// Starts the coordinator
- func start()
-
- /// The array containing any child Coordinators
- var childCoordinators: [Coordinator] { get set }
-
-}
-
-public extension Coordinator {
-
- /// Add a child coordinator to the parent
- public func addChildCoordinator(_ childCoordinator: Coordinator) {
- self.childCoordinators.append(childCoordinator)
- }
-
- /// Remove a child coordinator from the parent
- public func removeChildCoordinator(_ childCoordinator: Coordinator) {
- self.childCoordinators = self.childCoordinators.filter { $0 !== childCoordinator }
- }
-
-}
diff --git a/WireGuard/Coordinators/RootCoordinator.swift b/WireGuard/Coordinators/RootCoordinator.swift
deleted file mode 100644
index 79ca0ad..0000000
--- a/WireGuard/Coordinators/RootCoordinator.swift
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import UIKit
-
-public protocol RootViewControllerProvider: class {
- // The coordinators 'rootViewController'. It helps to think of this as the view
- // controller that can be used to dismiss the coordinator from the view hierarchy.
- var rootViewController: UIViewController { get }
-}
-
-/// A Coordinator type that provides a root UIViewController
-public typealias RootViewCoordinator = Coordinator & RootViewControllerProvider
diff --git a/WireGuard/Crypto/x25519.c b/WireGuard/Crypto/x25519.c
deleted file mode 100644
index 6569e11..0000000
--- a/WireGuard/Crypto/x25519.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+
- *
- * Copyright (C) 2015-2018 WireGuard LLC. All Rights Reserved.
- *
- * Curve25519 ECDH functions, based on TweetNaCl but cleaned up.
- */
-
-#include
-#include
-#include
-
-#include "x25519.h"
-
-typedef int64_t fe[16];
-
-static inline void carry(fe o)
-{
- int i;
-
- for (i = 0; i < 16; ++i) {
- o[(i + 1) % 16] += (i == 15 ? 38 : 1) * (o[i] >> 16);
- o[i] &= 0xffff;
- }
-}
-
-static inline void cswap(fe p, fe q, int b)
-{
- int i;
- int64_t t, c = ~(b - 1);
-
- for (i = 0; i < 16; ++i) {
- t = c & (p[i] ^ q[i]);
- p[i] ^= t;
- q[i] ^= t;
- }
-}
-
-static inline void pack(uint8_t *o, const fe n)
-{
- int i, j, b;
- fe m, t;
-
- memcpy(t, n, sizeof(t));
- carry(t);
- carry(t);
- carry(t);
- for (j = 0; j < 2; ++j) {
- m[0] = t[0] - 0xffed;
- for (i = 1; i < 15; ++i) {
- m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
- m[i - 1] &= 0xffff;
- }
- m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
- b = (m[15] >> 16) & 1;
- m[14] &= 0xffff;
- cswap(t, m, 1 - b);
- }
- for (i = 0; i < 16; ++i) {
- o[2 * i] = t[i] & 0xff;
- o[2 * i + 1] = t[i] >> 8;
- }
-}
-
-static inline void unpack(fe o, const uint8_t *n)
-{
- int i;
-
- for (i = 0; i < 16; ++i)
- o[i] = n[2 * i] + ((int64_t)n[2 * i + 1] << 8);
- o[15] &= 0x7fff;
-}
-
-static inline void add(fe o, const fe a, const fe b)
-{
- int i;
-
- for (i = 0; i < 16; ++i)
- o[i] = a[i] + b[i];
-}
-
-static inline void subtract(fe o, const fe a, const fe b)
-{
- int i;
-
- for (i = 0; i < 16; ++i)
- o[i] = a[i] - b[i];
-}
-
-static inline void multmod(fe o, const fe a, const fe b)
-{
- int i, j;
- int64_t t[31] = { 0 };
-
- for (i = 0; i < 16; ++i) {
- for (j = 0; j < 16; ++j)
- t[i + j] += a[i] * b[j];
- }
- for (i = 0; i < 15; ++i)
- t[i] += 38 * t[i + 16];
- memcpy(o, t, sizeof(fe));
- carry(o);
- carry(o);
-}
-
-static inline void invert(fe o, const fe i)
-{
- fe c;
- int a;
-
- memcpy(c, i, sizeof(c));
- for (a = 253; a >= 0; --a) {
- multmod(c, c, c);
- if (a != 2 && a != 4)
- multmod(c, c, i);
- }
- memcpy(o, c, sizeof(fe));
-}
-
-static void curve25519_shared_secret(uint8_t shared_secret[32], const uint8_t private_key[32], const uint8_t public_key[32])
-{
- static const fe a24 = { 0xdb41, 1 };
- uint8_t z[32];
- int64_t r;
- int i;
- fe a = { 1 }, b, c = { 0 }, d = { 1 }, e, f, x;
-
- memcpy(z, private_key, sizeof(z));
-
- z[31] = (z[31] & 127) | 64;
- z[0] &= 248;
-
- unpack(x, public_key);
- memcpy(b, x, sizeof(b));
-
- for (i = 254; i >= 0; --i) {
- r = (z[i >> 3] >> (i & 7)) & 1;
- cswap(a, b, (int)r);
- cswap(c, d, (int)r);
- add(e, a, c);
- subtract(a, a, c);
- add(c, b, d);
- subtract(b, b, d);
- multmod(d, e, e);
- multmod(f, a, a);
- multmod(a, c, a);
- multmod(c, b, e);
- add(e, a, c);
- subtract(a, a, c);
- multmod(b, a, a);
- subtract(c, d, f);
- multmod(a, c, a24);
- add(a, a, d);
- multmod(c, c, a);
- multmod(a, d, f);
- multmod(d, b, x);
- multmod(b, e, e);
- cswap(a, b, (int)r);
- cswap(c, d, (int)r);
- }
- invert(c, c);
- multmod(a, a, c);
- pack(shared_secret, a);
-}
-
-void curve25519_derive_public_key(uint8_t public_key[32], const uint8_t private_key[32])
-{
- static const uint8_t basepoint[32] = { 9 };
-
- curve25519_shared_secret(public_key, private_key, basepoint);
-}
-
-void curve25519_generate_private_key(uint8_t private_key[32])
-{
- CCRandomGenerateBytes(private_key, 32);
- private_key[31] = (private_key[31] & 127) | 64;
- private_key[0] &= 248;
-}
diff --git a/WireGuard/Crypto/x25519.h b/WireGuard/Crypto/x25519.h
deleted file mode 100644
index 7d8440d..0000000
--- a/WireGuard/Crypto/x25519.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef X25519_H
-#define X25519_H
-
-void curve25519_derive_public_key(unsigned char public_key[32], const unsigned char private_key[32]);
-void curve25519_generate_private_key(unsigned char private_key[32]);
-
-#endif
diff --git a/WireGuard/CustomViews/CopyableLabel.swift b/WireGuard/CustomViews/CopyableLabel.swift
deleted file mode 100644
index 1bca7e3..0000000
--- a/WireGuard/CustomViews/CopyableLabel.swift
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-
-@IBDesignable
-class CopyableLabel: UILabel {
- override func awakeFromNib() {
- super.awakeFromNib()
- let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
- self.addGestureRecognizer(gestureRecognizer)
- self.isUserInteractionEnabled = true
- }
-
- // MARK: - UIGestureRecognizer
- @objc func handleTapGesture(_ recognizer: UIGestureRecognizer) {
- guard recognizer.state == .recognized else { return }
-
- if let recognizerView = recognizer.view,
- let recognizerSuperView = recognizerView.superview, recognizerView.becomeFirstResponder() {
- let menuController = UIMenuController.shared
- menuController.setTargetRect(recognizerView.frame, in: recognizerSuperView)
- menuController.setMenuVisible(true, animated: true)
- }
- }
-
- override var canBecomeFirstResponder: Bool {
- return true
- }
-
- override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
- return (action == #selector(UIResponderStandardEditActions.copy(_:)))
-
- }
-
- override func copy(_ sender: Any?) {
- UIPasteboard.general.string = text
- }
-}
diff --git a/WireGuard/Extensions/String+Arrays.swift b/WireGuard/Extensions/String+Arrays.swift
deleted file mode 100644
index b142202..0000000
--- a/WireGuard/Extensions/String+Arrays.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-extension String {
-
- static func commaSeparatedStringFrom(elements: [String]) -> String {
- return elements.joined(separator: ",")
- }
-
- func commaSeparatedToArray() -> [String] {
- return components(separatedBy: .whitespaces)
- .joined()
- .split(separator: ",")
- .map(String.init)
- }
-
-}
diff --git a/WireGuard/Extensions/String+Base64.swift b/WireGuard/Extensions/String+Base64.swift
deleted file mode 100644
index ae70010..0000000
--- a/WireGuard/Extensions/String+Base64.swift
+++ /dev/null
@@ -1,14 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-extension String {
-
- func isBase64() -> Bool {
- let base64Predicate = NSPredicate(format: "SELF MATCHES %@", "^[a-zA-Z0-9+/]{43}=$")
- return base64Predicate.evaluate(with: self)
- }
-
-}
diff --git a/WireGuard/Info.plist b/WireGuard/Info.plist
deleted file mode 100644
index 842a2a2..0000000
--- a/WireGuard/Info.plist
+++ /dev/null
@@ -1,173 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleDisplayName
- ${PRODUCT_NAME}
- CFBundleDocumentTypes
-
-
- CFBundleTypeExtensions
-
- conf
-
- CFBundleTypeIconFiles
-
- icon_20pt
- icon_20pt@3x
- icon_60pt@3x
-
- CFBundleTypeName
- WireGuard configuration
- CFBundleTypeRole
- Viewer
- LSHandlerRank
- Owner
- LSItemContentTypes
-
- com.wireguard.config.quick
-
-
-
- CFBundleTypeExtensions
-
- zip
-
- CFBundleTypeIconFile
- zip
- CFBundleTypeIconFiles
-
- CFBundleTypeMIMETypes
-
- application/zip
- application/x-zip
- application/x-zip-compressed
-
- CFBundleTypeName
- WireGuard Config Zip
- CFBundleTypeOSTypes
-
- ZIP
-
- CFBundleTypeRole
- Viewer
- LSItemContentTypes
-
- com.pkware.zip-archive
-
-
-
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- WireGuardGoVersion
- unknown
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 1.0
- CFBundleVersion
- auto-generated
- LSRequiresIPhoneOS
-
- LSSupportsOpeningDocumentsInPlace
-
- NSCameraUsageDescription
- Camera is used to scan QR codes
- UIFileSharingEnabled
-
- UILaunchStoryboardName
- LaunchScreen
- UIRequiredDeviceCapabilities
-
- armv7
-
- UIStatusBarStyle
- UIStatusBarStyleLightContent
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UIViewControllerBasedStatusBarAppearance
-
- UTExportedTypeDeclarations
-
-
- UTTypeConformsTo
-
- public.data
-
- UTTypeDescription
- WireGuard configuration
- UTTypeIconFiles
-
- icon_20pt@3x
- icon_60pt@3x
-
- UTTypeIdentifier
- com.wireguard.config.quick
- UTTypeTagSpecification
-
- public.filename-extension
- conf
-
-
-
- UTImportedTypeDeclarations
-
-
- UTTypeConformsTo
-
- com.pkware.zip-archive
-
- UTTypeDescription
- WireGuard configuration
- UTTypeIconFiles
-
- icon_20pt@3x
- icon_60pt@3x
-
- UTTypeIdentifier
- com.wireguard.config.quick
- UTTypeTagSpecification
-
- public.filename-extension
- conf
-
-
-
- UTTypeConformsTo
-
- public.data
-
- UTTypeDescription
- WireGuard configurations
- UTTypeIconFiles
-
- icon_20pt.png
- icon_60pt@3x.png
-
- UTTypeIdentifier
- com.wireguard.config.quick.confs
- public.filename-extension
- zip
-
-
-
-
diff --git a/WireGuard/Log.swift b/WireGuard/Log.swift
deleted file mode 100644
index 7472934..0000000
--- a/WireGuard/Log.swift
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import os.log
-
-struct Log {
- static var general = OSLog(subsystem: "com.wireguard.ios", category: "general")
-}
diff --git a/WireGuard/Models/Attribute.swift b/WireGuard/Models/Attribute.swift
deleted file mode 100644
index 61e7246..0000000
--- a/WireGuard/Models/Attribute.swift
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-struct Attribute {
-
- enum Key: String, CaseIterable {
- case address = "Address"
- case allowedIPs = "AllowedIPs"
- case dns = "DNS"
- case endpoint = "Endpoint"
- case listenPort = "ListenPort"
- case mtu = "MTU"
- case persistentKeepalive = "PersistentKeepalive"
- case presharedKey = "PresharedKey"
- case privateKey = "PrivateKey"
- case publicKey = "PublicKey"
- }
-
- private static let separatorPattern = (try? NSRegularExpression(pattern: "\\s|=", options: []))!
-
- let line: String
- let key: Key
- let stringValue: String
- var arrayValue: [String] {
- return stringValue.commaSeparatedToArray()
- }
-
- static func match(line: String) -> Attribute? {
- guard let equalsIndex = line.firstIndex(of: "=") else { return nil }
- let keyString = line[.. NSFetchRequest {
- return NSFetchRequest(entityName: "Interface")
- }
-
- @NSManaged public var addresses: String?
- @NSManaged public var listenPort: Int16
- @NSManaged public var privateKey: String?
- @NSManaged public var mtu: Int32
- @NSManaged public var dns: String?
- @NSManaged public var tunnel: Tunnel?
-
-}
-
-// MARK: Generated accessors for adresses
-extension Interface {
-}
diff --git a/WireGuard/Models/Interface+Extension.swift b/WireGuard/Models/Interface+Extension.swift
deleted file mode 100644
index 848f29e..0000000
--- a/WireGuard/Models/Interface+Extension.swift
+++ /dev/null
@@ -1,100 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-extension Interface {
-
- var publicKey: String? {
- if let privateKeyString = privateKey, let privateKey = Data(base64Encoded: privateKeyString) {
- var publicKey = Data(count: 32)
- privateKey.withUnsafeBytes({ (privateKeyBytes) -> Void in
- publicKey.withUnsafeMutableBytes({ (mutableBytes) -> Void in
- curve25519_derive_public_key(mutableBytes, privateKeyBytes)
- })
- })
- return publicKey.base64EncodedString()
- } else {
- return nil
- }
- }
-
- func validate() throws {
- guard let privateKey = privateKey, !privateKey.isEmpty else {
- throw InterfaceValidationError.emptyPrivateKey
- }
-
- guard privateKey.isBase64() else {
- throw InterfaceValidationError.invalidPrivateKey
- }
-
- try addresses?.commaSeparatedToArray().forEach { address in
- do {
- try _ = CIDRAddress(stringRepresentation: address)
- } catch {
- throw InterfaceValidationError.invalidAddress(cause: error)
- }
- }
-
- try dns?.commaSeparatedToArray().forEach { address in
- do {
- try _ = Endpoint(endpointString: address, needsPort: false)
- } catch {
- throw InterfaceValidationError.invalidDNSServer(cause: error)
- }
- }
- }
-
- func parse(attribute: Attribute) throws {
- switch attribute.key {
- case .address:
- addresses = attribute.stringValue
- case .dns:
- dns = attribute.stringValue
- case .listenPort:
- if let port = Int16(attribute.stringValue) {
- listenPort = port
- }
- case .mtu:
- if let mtu = Int32(attribute.stringValue) {
- self.mtu = mtu
- }
- case .privateKey:
- privateKey = attribute.stringValue
- default:
- throw TunnelParseError.invalidLine(attribute.line)
- }
- }
-
- func export() -> String {
- var exportString = "[Interface]\n"
- if let privateKey = privateKey {
- exportString.append("PrivateKey=\(privateKey)\n")
- }
- if let addresses = addresses {
- exportString.append("Address=\(addresses)\n")
- }
- if let dns = dns {
- exportString.append("DNS=\(dns)\n")
- }
- if mtu > 0 {
- exportString.append("MTU=\(mtu)\n")
- }
- if listenPort > 0 {
- exportString.append("ListenPort=\(listenPort)\n")
- }
-
- exportString.append("\n")
-
- return exportString
- }
-
-}
-
-enum InterfaceValidationError: Error {
- case emptyPrivateKey
- case invalidPrivateKey
- case invalidAddress(cause: Error)
- case invalidDNSServer(cause: Error)
-}
diff --git a/WireGuard/Models/Peer+CoreDataClass.swift b/WireGuard/Models/Peer+CoreDataClass.swift
deleted file mode 100644
index d8c4664..0000000
--- a/WireGuard/Models/Peer+CoreDataClass.swift
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import CoreData
-
-@objc(Peer)
-public class Peer: NSManagedObject {
-
-}
diff --git a/WireGuard/Models/Peer+CoreDataProperties.swift b/WireGuard/Models/Peer+CoreDataProperties.swift
deleted file mode 100644
index 50132e7..0000000
--- a/WireGuard/Models/Peer+CoreDataProperties.swift
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import CoreData
-
-extension Peer {
-
- @nonobjc public class func fetchRequest() -> NSFetchRequest {
- return NSFetchRequest(entityName: "Peer")
- }
-
- @NSManaged public var publicKey: String?
- @NSManaged public var presharedKey: String?
- @NSManaged public var allowedIPs: String?
- @NSManaged public var endpoint: String?
- @NSManaged public var persistentKeepalive: Int32
- @NSManaged public var tunnel: Tunnel?
-
-}
diff --git a/WireGuard/Models/Peer+Extension.swift b/WireGuard/Models/Peer+Extension.swift
deleted file mode 100644
index 4472b0c..0000000
--- a/WireGuard/Models/Peer+Extension.swift
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-extension Peer {
-
- func validate() throws {
- guard let publicKey = publicKey, !publicKey.isEmpty else {
- throw PeerValidationError.emptyPublicKey
- }
-
- guard publicKey.isBase64() else {
- throw PeerValidationError.invalidPublicKey
- }
-
- guard let allowedIPs = allowedIPs, !allowedIPs.isEmpty else {
- throw PeerValidationError.nilAllowedIps
- }
-
- try allowedIPs.commaSeparatedToArray().forEach { address in
- do {
- try _ = CIDRAddress(stringRepresentation: address)
- } catch {
- throw PeerValidationError.invalidAllowedIPs(cause: error)
- }
- }
-
- if let endpoint = endpoint {
- do {
- try _ = Endpoint(endpointString: endpoint)
- } catch {
- throw PeerValidationError.invalidEndpoint(cause: error)
- }
- }
-
- guard persistentKeepalive >= 0, persistentKeepalive <= 65535 else {
- throw PeerValidationError.invalidPersistedKeepAlive
- }
- }
-
- func parse(attribute: Attribute) throws {
- switch attribute.key {
- case .allowedIPs:
- allowedIPs = attribute.stringValue
- case .endpoint:
- endpoint = attribute.stringValue
- case .persistentKeepalive:
- if let keepAlive = Int32(attribute.stringValue) {
- persistentKeepalive = keepAlive
- }
- case .presharedKey:
- presharedKey = attribute.stringValue
- case .publicKey:
- publicKey = attribute.stringValue
- default:
- throw TunnelParseError.invalidLine(attribute.line)
- }
- }
-
- func export() -> String {
- var exportString = "[Peer]\n"
- if let publicKey = publicKey {
- exportString.append("PublicKey=\(publicKey)\n")
- }
- if let presharedKey = presharedKey {
- exportString.append("PresharedKey=\(presharedKey)\n")
- }
- if let allowedIPs = allowedIPs {
- exportString.append("AllowedIPs=\(allowedIPs)\n")
- }
- if let endpoint = endpoint {
- exportString.append("Endpoint=\(endpoint)\n")
- }
- if persistentKeepalive > 0 {
- exportString.append("PersistentKeepalive=\(persistentKeepalive)\n")
- }
-
- exportString.append("\n")
-
- return exportString
- }
-
-}
-
-enum PeerValidationError: Error {
- case emptyPublicKey
- case invalidPublicKey
- case nilAllowedIps
- case invalidAllowedIPs(cause: Error)
- case invalidEndpoint(cause: Error)
- case invalidPersistedKeepAlive
-}
diff --git a/WireGuard/Models/Tunnel+CoreDataClass.swift b/WireGuard/Models/Tunnel+CoreDataClass.swift
deleted file mode 100644
index f26d33c..0000000
--- a/WireGuard/Models/Tunnel+CoreDataClass.swift
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import CoreData
-
-@objc(Tunnel)
-public class Tunnel: NSManagedObject {
-
-}
diff --git a/WireGuard/Models/Tunnel+CoreDataProperties.swift b/WireGuard/Models/Tunnel+CoreDataProperties.swift
deleted file mode 100644
index 2bfad02..0000000
--- a/WireGuard/Models/Tunnel+CoreDataProperties.swift
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import CoreData
-
-extension Tunnel {
-
- @nonobjc public class func fetchRequest() -> NSFetchRequest {
- return NSFetchRequest(entityName: "Tunnel")
- }
-
- @NSManaged public var tunnelIdentifier: String?
- @NSManaged public var title: String?
- @NSManaged public var interface: Interface?
- @NSManaged public var peers: NSOrderedSet?
-
-}
-
-// MARK: Generated accessors for peers
-extension Tunnel {
-
- @objc(insertObject:inPeersAtIndex:)
- @NSManaged public func insertIntoPeers(_ value: Peer, at idx: Int)
-
- @objc(removeObjectFromPeersAtIndex:)
- @NSManaged public func removeFromPeers(at idx: Int)
-
- @objc(insertPeers:atIndexes:)
- @NSManaged public func insertIntoPeers(_ values: [Peer], at indexes: NSIndexSet)
-
- @objc(removePeersAtIndexes:)
- @NSManaged public func removeFromPeers(at indexes: NSIndexSet)
-
- @objc(replaceObjectInPeersAtIndex:withObject:)
- @NSManaged public func replacePeers(at idx: Int, with value: Peer)
-
- @objc(replacePeersAtIndexes:withPeers:)
- @NSManaged public func replacePeers(at indexes: NSIndexSet, with values: [Peer])
-
- @objc(addPeersObject:)
- @NSManaged public func addToPeers(_ value: Peer)
-
- @objc(removePeersObject:)
- @NSManaged public func removeFromPeers(_ value: Peer)
-
- @objc(addPeers:)
- @NSManaged public func addToPeers(_ values: NSOrderedSet)
-
- @objc(removePeers:)
- @NSManaged public func removeFromPeers(_ values: NSOrderedSet)
-
-}
diff --git a/WireGuard/Models/Tunnel+Extension.swift b/WireGuard/Models/Tunnel+Extension.swift
deleted file mode 100644
index 99271a1..0000000
--- a/WireGuard/Models/Tunnel+Extension.swift
+++ /dev/null
@@ -1,212 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import CoreData
-
-extension Tunnel {
- public func generateProviderConfiguration() -> [String: Any] {
- var providerConfiguration = [String: Any]()
-
- providerConfiguration[PCKeys.title.rawValue] = self.title
- providerConfiguration[PCKeys.tunnelIdentifier.rawValue] = self.tunnelIdentifier
- providerConfiguration[PCKeys.endpoints.rawValue] = peers?.array.compactMap {($0 as? Peer)?.endpoint}.joined(separator: ", ")
- providerConfiguration[PCKeys.dns.rawValue] = interface?.dns
- providerConfiguration[PCKeys.addresses.rawValue] = interface?.addresses
- if let mtu = interface?.mtu, mtu > 0 {
- providerConfiguration[PCKeys.mtu.rawValue] = NSNumber(value: mtu)
- }
-
- 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 = ""
-
- if let hexPrivateKey = base64KeyToHex(interface.privateKey) {
- settingsString += "private_key=\(hexPrivateKey)\n"
- }
- if interface.listenPort > 0 {
- settingsString += "listen_port=\(interface.listenPort)\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)\n"
- }
- if let presharedKey = peer.presharedKey {
- settingsString += "preshared_key=\(presharedKey)\n"
- }
- if let endpoint = peer.endpoint {
- settingsString += "endpoint=\(endpoint)\n"
- }
- if peer.persistentKeepalive > 0 {
- settingsString += "persistent_keepalive_interval=\(peer.persistentKeepalive)\n"
- }
- if let allowedIPs = peer.allowedIPs?.commaSeparatedToArray() {
- allowedIPs.forEach {
- settingsString += "allowed_ip=\($0.trimmingCharacters(in: .whitespaces))\n"
- }
- }
-
- return settingsString
- }
-
- func validate() throws {
- let nameRegex = "[a-zA-Z0-9_=+.-]{1,15}"
- let nameTest = NSPredicate(format: "SELF MATCHES %@", nameRegex)
- guard let title = title, nameTest.evaluate(with: title) else {
- throw TunnelValidationError.invalidTitle
- }
-
- let fetchRequest: NSFetchRequest = Tunnel.fetchRequest()
- fetchRequest.predicate = NSPredicate(format: "title == %@", title)
- guard (try? managedObjectContext?.count(for: fetchRequest)) == 1 else {
- throw TunnelValidationError.titleExists
- }
-
- guard let interface = interface else {
- throw TunnelValidationError.nilInterface
- }
-
- try interface.validate()
-
- guard let peers = peers else {
- throw TunnelValidationError.nilPeers
- }
-
- try peers.forEach {
- guard let peer = $0 as? Peer else {
- throw TunnelValidationError.invalidPeer
- }
-
- try peer.validate()
- }
- }
-
- static func fromConfig(_ text: String, context: NSManagedObjectContext) throws -> Tunnel {
- let lines = text.split(separator: "\n")
-
- var currentPeer: Peer?
- var isInInterfaceSection = false
-
- var tunnel: Tunnel!
- context.performAndWait {
- tunnel = Tunnel(context: context)
- tunnel.interface = Interface(context: context)
- }
- tunnel.tunnelIdentifier = UUID().uuidString
-
- for line in lines {
- var trimmedLine: String
- if let commentRange = line.range(of: "#") {
- trimmedLine = String(line[.. 0 else { continue }
-
- if "[interface]" == line.lowercased() {
- currentPeer = nil
- isInInterfaceSection = true
- } else if "[peer]" == line.lowercased() {
- context.performAndWait { currentPeer = Peer(context: context) }
- tunnel.insertIntoPeers(currentPeer!, at: tunnel.peers?.count ?? 0)
- isInInterfaceSection = false
- } else if isInInterfaceSection, let attribute = Attribute.match(line: String(line)) {
- try tunnel.interface!.parse(attribute: attribute)
- } else if let currentPeer = currentPeer, let attribute = Attribute.match(line: String(line)) {
- try currentPeer.parse(attribute: attribute)
- } else {
- throw TunnelParseError.invalidLine(String(line))
- }
- }
-
- if !isInInterfaceSection && currentPeer == nil {
- throw TunnelParseError.noConfigInfo
- }
-
- return tunnel
- }
-
- func export() -> String {
- var exportString = ""
- if let interfaceExport = self.interface?.export() {
- exportString.append(interfaceExport)
- }
-
- if let peers = peers?.array as? [Peer] {
- peers.forEach {
- exportString.append($0.export())
- }
- }
-
- return exportString
- }
-
-}
-
-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
-}
-
-enum TunnelValidationError: Error {
- case invalidTitle
- case titleExists
- case nilInterface
- case nilPeers
- case invalidPeer
-}
-
-enum TunnelParseError: Error {
- case invalidLine(_ line: String)
- case noConfigInfo
-}
diff --git a/WireGuard/Models/WireGuard.xcdatamodeld/WireGuard.xcdatamodel/contents b/WireGuard/Models/WireGuard.xcdatamodeld/WireGuard.xcdatamodel/contents
deleted file mode 100644
index eeb1155..0000000
--- a/WireGuard/Models/WireGuard.xcdatamodeld/WireGuard.xcdatamodel/contents
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/WireGuard/ViewControllers/Identifyable.swift b/WireGuard/ViewControllers/Identifyable.swift
deleted file mode 100644
index c94a399..0000000
--- a/WireGuard/ViewControllers/Identifyable.swift
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-import UIKit
-
-public protocol Identifyable: class {
- static var identifier: String { get }
-}
-
-public extension Identifyable {
- static var identifier: String {
- return String(describing: Self.self)
- }
-}
-
-extension UIStoryboard {
-
- public func instantiateViewController(type: T.Type) -> T where T: UIViewController {
- return self.instantiateViewController(withIdentifier: type.identifier) as! T // swiftlint:disable:this force_cast
- }
-}
diff --git a/WireGuard/ViewControllers/QRScanViewController.swift b/WireGuard/ViewControllers/QRScanViewController.swift
deleted file mode 100644
index 30fd79d..0000000
--- a/WireGuard/ViewControllers/QRScanViewController.swift
+++ /dev/null
@@ -1,152 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import AVFoundation
-import CoreData
-import UIKit
-
-protocol QRScanViewControllerDelegate: class {
- func didSave(tunnel: Tunnel, qrScanViewController: QRScanViewController)
- func didCancel(qrScanViewController: QRScanViewController)
-}
-
-class QRScanViewController: UIViewController {
-
- private var viewContext: NSManagedObjectContext!
- private weak var delegate: QRScanViewControllerDelegate?
- var captureSession: AVCaptureSession? = AVCaptureSession()
- let metadataOutput = AVCaptureMetadataOutput()
- var previewLayer: AVCaptureVideoPreviewLayer!
-
- func configure(context: NSManagedObjectContext, delegate: QRScanViewControllerDelegate? = nil) {
- viewContext = context
- self.delegate = delegate
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- guard let videoCaptureDevice = AVCaptureDevice.default(for: .video),
- let videoInput = try? AVCaptureDeviceInput(device: videoCaptureDevice),
- let captureSession = captureSession,
- captureSession.canAddInput(videoInput),
- captureSession.canAddOutput(metadataOutput) else {
- scanDidEncounterError(title: "Scanning Not Supported", message: "This device does not have the ability to scan QR codes.")
- return
- }
-
- captureSession.addInput(videoInput)
- captureSession.addOutput(metadataOutput)
-
- metadataOutput.setMetadataObjectsDelegate(self, queue: .main)
- metadataOutput.metadataObjectTypes = [.qr]
-
- previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
- previewLayer.frame = view.layer.bounds
- previewLayer.videoGravity = .resizeAspectFill
- view.layer.insertSublayer(previewLayer, at: 0)
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
-
- if captureSession?.isRunning == false {
- captureSession?.startRunning()
- }
- }
-
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
-
- if captureSession?.isRunning == true {
- captureSession?.stopRunning()
- }
- }
-
- override func viewDidLayoutSubviews() {
- super.viewDidLayoutSubviews()
-
- if let connection = previewLayer.connection {
-
- let currentDevice: UIDevice = UIDevice.current
-
- let orientation: UIDeviceOrientation = currentDevice.orientation
-
- let previewLayerConnection: AVCaptureConnection = connection
-
- if previewLayerConnection.isVideoOrientationSupported {
-
- switch orientation {
- case .portrait:
- previewLayerConnection.videoOrientation = .portrait
- case .landscapeRight:
- previewLayerConnection.videoOrientation = .landscapeLeft
- case .landscapeLeft:
- previewLayerConnection.videoOrientation = .landscapeRight
- case .portraitUpsideDown:
- previewLayerConnection.videoOrientation = .portraitUpsideDown
- default:
- previewLayerConnection.videoOrientation = .portrait
-
- }
- }
- }
-
- previewLayer.frame = self.view.bounds
- }
-
- func scanDidComplete(withCode code: String) {
- do {
- let tunnel = try Tunnel.fromConfig(code, context: viewContext)
- let alert = UIAlertController(title: NSLocalizedString("Enter a title for new tunnel", comment: ""), message: nil, preferredStyle: .alert)
- alert.addTextField(configurationHandler: nil)
- alert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: { [weak self] _ in
- self?.delegate?.didCancel(qrScanViewController: self!)
- }))
- alert.addAction(UIAlertAction(title: NSLocalizedString("Save", comment: ""), style: .default, handler: { [weak self] _ in
- do {
- tunnel.title = alert.textFields?[0].text
- try self?.viewContext.save()
- self?.delegate?.didSave(tunnel: tunnel, qrScanViewController: self!)
- } catch {
- self?.scanDidEncounterError(title: "Invalid Code", message: "The scanned code is not a valid WireGuard config file.")
- }
- }))
-
- self.present(alert, animated: true)
-
- } catch {
- scanDidEncounterError(title: "Invalid Code", message: "The scanned code is not a valid WireGuard config file.")
- }
- }
-
- func scanDidEncounterError(title: String, message: String) {
- let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
- alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak self] _ in
- self?.navigationController?.popViewController(animated: true)
- }))
- present(alertController, animated: true)
- captureSession = nil
- }
-
-}
-
-extension QRScanViewController: AVCaptureMetadataOutputObjectsDelegate {
- func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
- captureSession?.stopRunning()
-
- guard let metadataObject = metadataObjects.first,
- let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject,
- let stringValue = readableObject.stringValue else {
- scanDidEncounterError(title: "Invalid Code", message: "The scanned code could not be read.")
- return
- }
-
- AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
- scanDidComplete(withCode: stringValue)
- }
-
-}
-
-extension QRScanViewController: Identifyable {}
diff --git a/WireGuard/ViewControllers/SetttingsTableViewController.swift b/WireGuard/ViewControllers/SetttingsTableViewController.swift
deleted file mode 100644
index 50832eb..0000000
--- a/WireGuard/ViewControllers/SetttingsTableViewController.swift
+++ /dev/null
@@ -1,77 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-import PromiseKit
-
-enum GoVersionError: Error {
- case noDelegate
-}
-
-protocol SettingsTableViewControllerDelegate: class {
- func exportTunnels(settingsTableViewController: SettingsTableViewController, sourceView: UIView)
-}
-
-class SettingsTableViewController: UITableViewController {
-
- weak var delegate: SettingsTableViewControllerDelegate?
- @IBOutlet weak var versionInfoCell: UITableViewCell!
- @IBOutlet weak var goVersionInfoCell: UITableViewCell!
- @IBOutlet weak var exportCell: UITableViewCell!
-
- @IBOutlet weak var versionInfoLabel: UILabel!
- @IBOutlet weak var goVersionInfoLabel: UILabel!
-
- override func viewDidLoad() {
- super.viewDidLoad()
- versionInfoLabel.text = versionInformation
- goVersionInfoLabel.text = goVersionInformation
- }
-
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- if let cell = tableView.cellForRow(at: indexPath) {
- switch cell {
- case versionInfoCell, goVersionInfoCell:
- UIPasteboard.general.string = ["WireGuard for iOS:", versionInformation, "Go userspace backend:", goVersionInfoLabel.text ?? ""].joined(separator: "\n")
- showCopyConfirmation()
- case exportCell:
- delegate?.exportTunnels(settingsTableViewController: self, sourceView: exportCell)
- default:
- ()
- }
- tableView.deselectRow(at: indexPath, animated: true)
- }
- }
-
- var versionInformation: String {
- var versionElements: [String] = []
- if let appBuildNumber = Bundle.main.infoDictionary!["CFBundleVersion"] as? String, let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as? String {
- versionElements.append(appVersion)
- versionElements.append("(\(appBuildNumber))")
- }
-
- return versionElements.joined(separator: " ")
- }
-
- var goVersionInformation: String {
- return Bundle.main.infoDictionary!["WireGuardGoVersion"] as? String ?? "Unknown!!!"
- }
-
- private func showNotEnabledAlert() {
- let notEnabledAlertController = UIAlertController(title: NSLocalizedString("Go version", comment: ""), message: NSLocalizedString("Enable a WireGuard config by connecting or by selecting one in the VPN section of the device Settings app.", comment: ""), preferredStyle: .alert)
- notEnabledAlertController.addAction(UIAlertAction(title: NSLocalizedString("Ok", comment: "Generic OK button"), style: .default, handler: nil))
-
- present(notEnabledAlertController, animated: true, completion: nil)
- }
-
- private func showCopyConfirmation() {
- let confirmationAlertController = UIAlertController(title: NSLocalizedString("Copied version information", comment: ""), message: UIPasteboard.general.string, preferredStyle: .alert)
- confirmationAlertController.addAction(UIAlertAction(title: NSLocalizedString("Ok", comment: "Generic OK button"), style: .default, handler: nil))
-
- present(confirmationAlertController, animated: true, completion: nil)
-
- }
-}
-
-extension SettingsTableViewController: Identifyable {}
diff --git a/WireGuard/ViewControllers/TunnelConfigurationTableViewController.swift b/WireGuard/ViewControllers/TunnelConfigurationTableViewController.swift
deleted file mode 100644
index 65679c7..0000000
--- a/WireGuard/ViewControllers/TunnelConfigurationTableViewController.swift
+++ /dev/null
@@ -1,300 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-import CoreData
-import BNRCoreDataStack
-import PromiseKit
-
-protocol TunnelConfigurationTableViewControllerDelegate: class {
- func didSave(tunnel: Tunnel, tunnelConfigurationTableViewController: TunnelConfigurationTableViewController)
- func showSettings()
-}
-
-class TunnelConfigurationTableViewController: UITableViewController {
-
- @IBOutlet weak var saveButton: UIBarButtonItem!
-
- private var viewContext: NSManagedObjectContext!
- private weak var delegate: TunnelConfigurationTableViewControllerDelegate?
- private var tunnel: Tunnel!
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- // Get rid of seperator lines in table.
- tableView.tableFooterView = UIView(frame: CGRect.zero)
- }
-
- func configure(context: NSManagedObjectContext, delegate: TunnelConfigurationTableViewControllerDelegate? = nil, tunnel: Tunnel? = nil) {
- viewContext = context
- self.delegate = delegate
- self.tunnel = tunnel ?? generateNewTunnelConfig()
- }
-
- private func generateNewTunnelConfig() -> Tunnel {
- var tunnel: Tunnel! = nil
-
- viewContext.performAndWait {
- tunnel = Tunnel(context: viewContext)
- tunnel.tunnelIdentifier = UUID().uuidString
-
- let interface = Interface(context: viewContext)
-
- tunnel.interface = interface
- }
- return tunnel
- }
-
- @IBAction func showSettings(_ sender: Any) {
- delegate?.showSettings()
- }
-
- @IBAction func addPeer(_ sender: Any) {
- if let moc = tunnel.managedObjectContext {
- tableView.beginUpdates()
- let insertedAt = IndexPath(row: tunnel.peers?.count ?? 0, section: 1)
- tableView.insertRows(at: [insertedAt], with: .automatic)
-
- let peer = Peer(context: moc)
- tunnel.addToPeers(peer)
-
- tableView.endUpdates()
- tableView.scrollToRow(at: insertedAt, at: .middle, animated: true)
- }
- }
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return 3
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- switch section {
- case 1:
- return tunnel?.peers?.count ?? 1
- default:
- return 1
- }
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- switch indexPath.section {
- case 0:
- let cell = tableView.dequeueReusableCell(type: InterfaceTableViewCell.self, for: indexPath)
- cell.model = tunnel.interface
- cell.delegate = self
- return cell
- case 1:
- let cell = tableView.dequeueReusableCell(type: PeerTableViewCell.self, for: indexPath)
- if let peer = tunnel.peers?.object(at: indexPath.row) as? Peer {
- cell.peer = peer
- } else {
- let peer = Peer(context: tunnel.managedObjectContext!)
- tunnel.addToPeers(peer)
- cell.peer = peer
- }
- cell.delegate = self
- return cell
- default:
- let cell = tableView.dequeueReusableCell(type: AddPeerTableViewCell.self, for: indexPath)
- cell.tunnel = tunnel
- return cell
- }
- }
-
- @IBAction func saveTunnelConfiguration(_ sender: Any) {
- Promise(resolver: { (seal) in
- do {
- try tunnel.validate()
- } catch {
- seal.reject(error)
- return
- }
-
- viewContext.perform({
- self.viewContext.saveContext({ (result) in
- switch result {
- case .success:
- seal.fulfill(())
- case .failure(let error):
- seal.reject(error)
- }
- })
- })
- }).then { () -> Promise in
- self.delegate?.didSave(tunnel: self.tunnel, tunnelConfigurationTableViewController: self)
- return Promise.value(())
- }.catch { error in
- let alert = UIAlertController(title: "Error", message: "\(error)", preferredStyle: .alert)
- alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
- self.present(alert, animated: true, completion: nil)
- }
- }
-}
-
-extension TunnelConfigurationTableViewController: PeerTableViewCellDelegate {
- func delete(peer: Peer) {
- if let moc = tunnel.managedObjectContext {
- tableView.beginUpdates()
- let deletedAt = IndexPath(row: tunnel.peers?.index(of: peer) ?? 0, section: 1)
- tableView.deleteRows(at: [deletedAt], with: .automatic)
- tunnel.removeFromPeers(peer)
- moc.delete(peer)
- tableView.endUpdates()
- }
- }
-}
-
-extension TunnelConfigurationTableViewController: InterfaceTableViewCellDelegate {
- func generateKeys() {
- if let moc = tunnel.managedObjectContext {
- moc.perform {
- var privateKey = Data(count: 32)
- privateKey.withUnsafeMutableBytes { (mutableBytes) -> Void in
- curve25519_generate_private_key(mutableBytes)
- }
-
- self.tunnel.interface?.privateKey = privateKey.base64EncodedString()
- }
- }
- self.tableView.reloadData()
- }
-}
-
-protocol InterfaceTableViewCellDelegate: class {
- func generateKeys()
-}
-
-class InterfaceTableViewCell: UITableViewCell {
- var model: Interface! {
- didSet {
- nameField.text = model.tunnel?.title
- addressesField.text = model.addresses
- privateKeyField.text = model.privateKey
- publicKeyField.text = model.publicKey
-
- listenPortField.text = model.listenPort > 0 ? String(model.listenPort) : nil
- dnsField.text = model.dns
- mtuField.text = model.mtu > 0 ? String(model.mtu) : nil
- }
- }
-
- weak var delegate: InterfaceTableViewCellDelegate?
-
- @IBOutlet weak var nameField: UITextField!
- @IBOutlet weak var addressesField: UITextField!
- @IBOutlet weak var privateKeyField: UITextField!
- @IBOutlet weak var publicKeyField: CopyableLabel!
- @IBOutlet weak var listenPortField: UITextField!
- @IBOutlet weak var dnsField: UITextField!
- @IBOutlet weak var mtuField: UITextField!
-
- @IBAction func generateTapped(_ sender: Any) {
- delegate?.generateKeys()
- }
-}
-
-extension InterfaceTableViewCell: UITextFieldDelegate {
-
- @IBAction
- func textfieldDidChange(_ sender: UITextField) {
- let string = sender.text
-
- if sender == nameField {
- model.tunnel?.title = string
- } else if sender == privateKeyField {
- model.privateKey = string
- publicKeyField.text = model.publicKey
- } else if sender == addressesField {
- model.addresses = string
- } else if sender == listenPortField {
- if let string = string, let port = Int16(string) {
- model.listenPort = port
- } else {
- model.listenPort = 0
- }
- } else if sender == dnsField {
- model.dns = string
- } else if sender == mtuField {
- if let string = string, let mtu = Int32(string) {
- model.mtu = mtu
- } else {
- model.mtu = 0
- }
- }
- }
-
- func textFieldDidEndEditing(_ textField: UITextField) {
- if textField == addressesField {
- if let addresses = model.addresses?.commaSeparatedToArray() {
- textField.text = addresses.compactMap { try? CIDRAddress(stringRepresentation: $0 ) }.compactMap { $0?.stringRepresentation }.joined(separator: ", ")
- }
- }
- }
-}
-
-protocol PeerTableViewCellDelegate: class {
- func delete(peer: Peer)
-}
-
-class PeerTableViewCell: UITableViewCell {
- var peer: Peer! {
- didSet {
- publicKeyField.text = peer.publicKey
- preSharedKeyField.text = peer.presharedKey
- allowedIpsField.text = peer.allowedIPs
- endpointField.text = peer.endpoint
- persistentKeepaliveField.text = peer.persistentKeepalive > 0 ? String(peer.persistentKeepalive) : nil
- }
- }
- weak var delegate: PeerTableViewCellDelegate?
-
- @IBOutlet weak var publicKeyField: UITextField!
- @IBOutlet weak var preSharedKeyField: UITextField!
- @IBOutlet weak var allowedIpsField: UITextField!
- @IBOutlet weak var endpointField: UITextField!
- @IBOutlet weak var persistentKeepaliveField: UITextField!
-
- @IBAction func deletePeer(_ sender: Any) {
- delegate?.delete(peer: peer)
- }
-}
-
-extension PeerTableViewCell: UITextFieldDelegate {
- @IBAction
- func textfieldDidChange(_ sender: UITextField) {
- let string = sender.text
-
- if sender == publicKeyField {
- peer.publicKey = string
- } else if sender == preSharedKeyField {
- peer.presharedKey = string
- } else if sender == allowedIpsField {
- peer.allowedIPs = string
- } else if sender == endpointField {
- peer.endpoint = string
- } else if sender == persistentKeepaliveField {
- if let string = string, let persistentKeepalive = Int32(string) {
- peer.persistentKeepalive = persistentKeepalive
- } else {
- peer.persistentKeepalive = 0
- }
- }
- }
-}
-
-class AddPeerTableViewCell: UITableViewCell {
- var tunnel: Tunnel!
-
- @IBAction func addPeer(_ sender: Any) {
- if let moc = tunnel.managedObjectContext {
- tunnel.addToPeers(Peer(context: moc))
- }
- }
-}
-
-extension TunnelConfigurationTableViewController: Identifyable {}
-extension InterfaceTableViewCell: Identifyable {}
-extension PeerTableViewCell: Identifyable {}
-extension AddPeerTableViewCell: Identifyable {}
diff --git a/WireGuard/ViewControllers/TunnelInfoTableViewController.swift b/WireGuard/ViewControllers/TunnelInfoTableViewController.swift
deleted file mode 100644
index 1eb898a..0000000
--- a/WireGuard/ViewControllers/TunnelInfoTableViewController.swift
+++ /dev/null
@@ -1,194 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-import CoreData
-import NetworkExtension
-
-import BNRCoreDataStack
-import PromiseKit
-
-protocol TunnelInfoTableViewControllerDelegate: class {
- func connect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController)
- func disconnect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController)
- func configure(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController)
- func showSettings()
- func status(for tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) -> NEVPNStatus
-}
-
-class TunnelInfoTableViewController: UITableViewController {
-
- @IBOutlet weak var editButton: UIBarButtonItem!
-
- private var viewContext: NSManagedObjectContext!
- private weak var delegate: TunnelInfoTableViewControllerDelegate?
- private var tunnel: Tunnel!
-
- func configure(context: NSManagedObjectContext, delegate: TunnelInfoTableViewControllerDelegate? = nil, tunnel: Tunnel) {
- viewContext = context
- self.delegate = delegate
- self.tunnel = tunnel
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- // Get rid of seperator lines in table.
- tableView.tableFooterView = UIView(frame: CGRect.zero)
-
- NotificationCenter.default.addObserver(self,
- selector: #selector(VPNStatusDidChange(notification:)),
- name: .NEVPNStatusDidChange,
- object: nil)
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super .viewWillAppear(animated)
-
- self.tableView.reloadData()
- }
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return 2
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- switch section {
- case 1:
- return tunnel?.peers?.count ?? 0
- default:
- return 1
- }
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- switch indexPath.section {
- case 0:
- let cell = tableView.dequeueReusableCell(type: InterfaceInfoTableViewCell.self, for: indexPath)
- cell.delegate = self
- cell.configure(model: tunnel.interface, status: delegate?.status(for: tunnel, tunnelInfoTableViewController: self) ?? .invalid)
- return cell
- default:
- let cell = tableView.dequeueReusableCell(type: PeerInfoTableViewCell.self, for: indexPath)
- if let peer = tunnel.peers?.object(at: indexPath.row) as? Peer {
- cell.peer = peer
- } else {
- let peer = Peer(context: tunnel.managedObjectContext!)
- tunnel.addToPeers(peer)
- cell.peer = peer
- }
- return cell
- }
- }
-
- @IBAction func showSettings(_ sender: Any) {
- delegate?.showSettings()
- }
-
- @IBAction func editTunnelConfiguration(_ sender: Any) {
- delegate?.configure(tunnel: self.tunnel, tunnelInfoTableViewController: self)
- }
-
- @objc private func VPNStatusDidChange(notification: NSNotification) {
- guard let session = notification.object as? NETunnelProviderSession else {
- return
- }
-
- guard let prot = session.manager.protocolConfiguration as? NETunnelProviderProtocol else {
- return
- }
-
- guard let changedTunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
- return
- }
-
- guard tunnel.tunnelIdentifier == changedTunnelIdentifier else {
- return
- }
-
- self.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .none)
- }
-}
-
-extension TunnelInfoTableViewController: InterfaceInfoTableViewCellDelegate {
- func connect(tunnelIdentifier: String) {
- delegate?.connect(tunnel: tunnel, tunnelInfoTableViewController: self)
- }
-
- func disconnect(tunnelIdentifier: String) {
- delegate?.disconnect(tunnel: tunnel, tunnelInfoTableViewController: self)
- }
-}
-
-protocol InterfaceInfoTableViewCellDelegate: class {
- func connect(tunnelIdentifier: String)
- func disconnect(tunnelIdentifier: String)
-}
-
-class InterfaceInfoTableViewCell: UITableViewCell {
- weak var delegate: InterfaceInfoTableViewCellDelegate?
- private var model: Interface! {
- didSet {
- nameField.text = model.tunnel?.title
- addressesField.text = model.addresses
- publicKeyField.text = model.publicKey
- }
- }
-
- func configure(model: Interface!, status: NEVPNStatus) {
- self.model = model
-
- if status == .connecting || status == .disconnecting || status == .reasserting {
- activityIndicator.startAnimating()
- tunnelSwitch.isHidden = true
- } else {
- activityIndicator.stopAnimating()
- tunnelSwitch.isHidden = false
- }
-
- tunnelSwitch.isOn = status == .connected
- tunnelSwitch.onTintColor = status == .invalid || status == .reasserting ? .gray : .green
- tunnelSwitch.isEnabled = true
- }
-
- @IBAction func tunnelSwitchChanged(_ sender: Any) {
- tunnelSwitch.isEnabled = false
-
- guard let tunnelIdentifier = model.tunnel?.tunnelIdentifier else {
- return
- }
-
- if tunnelSwitch.isOn {
- delegate?.connect(tunnelIdentifier: tunnelIdentifier)
- } else {
- delegate?.disconnect(tunnelIdentifier: tunnelIdentifier)
- }
- }
-
- @IBOutlet weak var nameField: UILabel!
- @IBOutlet weak var addressesField: UILabel!
- @IBOutlet weak var publicKeyField: CopyableLabel!
- @IBOutlet weak var tunnelSwitch: UISwitch!
- @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
-}
-
-class PeerInfoTableViewCell: UITableViewCell {
- var peer: Peer! {
- didSet {
- publicKeyField.text = peer.publicKey
- allowedIpsField.text = peer.allowedIPs
- endpointField.text = peer.endpoint
- }
- }
-
- @IBOutlet weak var publicKeyField: CopyableLabel!
- @IBOutlet weak var allowedIpsField: UILabel!
- @IBOutlet weak var endpointField: UILabel!
- @IBOutlet weak var copiedStatusLabel: UILabel!
-
-}
-
-extension TunnelInfoTableViewController: Identifyable {}
-extension InterfaceInfoTableViewCell: Identifyable {}
-extension PeerInfoTableViewCell: Identifyable {}
diff --git a/WireGuard/ViewControllers/TunnelsTableViewController.swift b/WireGuard/ViewControllers/TunnelsTableViewController.swift
deleted file mode 100644
index 26932d9..0000000
--- a/WireGuard/ViewControllers/TunnelsTableViewController.swift
+++ /dev/null
@@ -1,308 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import UIKit
-import os.log
-import CoreData
-
-import BNRCoreDataStack
-import NetworkExtension
-
-protocol TunnelsTableViewControllerDelegate: class {
- func addProvider(tunnelsTableViewController: TunnelsTableViewController)
- func connect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController)
- func disconnect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController)
- func info(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController)
- func delete(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController)
- func status(for tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) -> NEVPNStatus
- func showSettings()
-}
-
-class TunnelsTableViewController: UITableViewController {
- weak var delegate: TunnelsTableViewControllerDelegate?
-
- var viewContext: NSManagedObjectContext!
-
- @IBOutlet var settingsButton: UIBarButtonItem!
- @IBOutlet var editButton: UIBarButtonItem!
- @IBOutlet var doneButton: UIBarButtonItem!
-
- private lazy var fetchedResultsController: FetchedResultsController = {
- let fetchRequest = NSFetchRequest()
- fetchRequest.entity = Tunnel.entity()
- fetchRequest.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
- let frc = FetchedResultsController(fetchRequest: fetchRequest,
- managedObjectContext: viewContext)
- frc.setDelegate(self.frcDelegate)
- return frc
- }()
-
- public func updateStatus(for tunnelIdentifier: String) {
- viewContext.perform {
- do {
- let tunnel = try Tunnel.findFirstInContext(self.viewContext, predicate: NSPredicate(format: "tunnelIdentifier == %@", tunnelIdentifier))
- if let tunnel = tunnel {
- if let indexPath = self.fetchedResultsController.indexPathForObject(tunnel) {
- self.tableView.reloadRows(at: [indexPath], with: .none)
- }
- }
- } catch {
- os_log("Unable to load tunnel for tunnel identifier: %{public}@", log: Log.general, type: .error, error.localizedDescription)
-
- }
- }
- }
-
- private lazy var frcDelegate: TunnelFetchedResultsControllerDelegate = { // swiftlint:disable:this weak_delegate
- return TunnelFetchedResultsControllerDelegate(tableView: self.tableView)
- }()
-
- override func viewDidLoad() {
- super.viewDidLoad()
- do {
- try fetchedResultsController.performFetch()
- } catch {
- print("Failed to fetch objects: \(error)")
- }
-
- // Get rid of seperator lines in table.
- tableView.tableFooterView = UIView(frame: CGRect.zero)
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
- updateBarButtons()
- }
-
- @IBAction func editTunnels(_ sender: Any) {
- tableView.setEditing(!tableView.isEditing, animated: true)
- updateBarButtons()
-
- }
-
- private func updateBarButtons() {
- navigationController?.setToolbarHidden(tableView.isEditing, animated: true)
- if tableView.isEditing {
- self.navigationItem.setRightBarButtonItems([doneButton], animated: true)
- } else {
- self.navigationItem.setRightBarButtonItems([settingsButton, editButton], animated: true)
- }
- }
-
- @IBAction func showSettings(_ sender: Any) {
- delegate?.showSettings()
- }
-
- @IBAction func addProvider(_ sender: UIBarButtonItem) {
- delegate?.addProvider(tunnelsTableViewController: self)
- }
-
- override func numberOfSections(in tableView: UITableView) -> Int {
- return 1
- }
-
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return fetchedResultsController.sections?[0].objects.count ?? 0
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = tableView.dequeueReusableCell(type: TunnelTableViewCell.self, for: indexPath)
- cell.delegate = self
-
- guard let sections = fetchedResultsController.sections else {
- fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
- }
-
- let section = sections[indexPath.section]
- let tunnel = section.objects[indexPath.row]
-
- cell.configure(tunnel: tunnel, status: delegate?.status(for: tunnel, tunnelsTableViewController: self) ?? .invalid)
-
- return cell
- }
-
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- guard let sections = fetchedResultsController.sections else {
- fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
- }
-
- let section = sections[indexPath.section]
- let tunnel = section.objects[indexPath.row]
-
- delegate?.info(tunnel: tunnel, tunnelsTableViewController: self)
-
- tableView.deselectRow(at: indexPath, animated: true)
- }
-
- override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
- guard let sections = fetchedResultsController.sections else {
- fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
- }
-
- let section = sections[indexPath.section]
- let tunnel = section.objects[indexPath.row]
-
- delegate?.info(tunnel: tunnel, tunnelsTableViewController: self)
-
- }
-
- override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
- return true
- }
-
- override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
- if editingStyle == .delete {
-
- guard let sections = fetchedResultsController.sections else {
- fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
- }
-
- let section = sections[indexPath.section]
- let tunnel = section.objects[indexPath.row]
-
- delegate?.delete(tunnel: tunnel, tunnelsTableViewController: self)
- }
- }
-}
-
-extension TunnelsTableViewController: TunnelTableViewCellDelegate {
- func connect(tunnelIdentifier: String) {
- let tunnel = try? Tunnel.findFirstInContext(self.viewContext, predicate: NSPredicate(format: "tunnelIdentifier == %@", tunnelIdentifier))
- if let tunnel = tunnel {
- self.delegate?.connect(tunnel: tunnel!, tunnelsTableViewController: self)
- }
- }
-
- func disconnect(tunnelIdentifier: String) {
- let tunnel = try? Tunnel.findFirstInContext(self.viewContext, predicate: NSPredicate(format: "tunnelIdentifier == %@", tunnelIdentifier))
- if let tunnel = tunnel {
- self.delegate?.disconnect(tunnel: tunnel!, tunnelsTableViewController: self)
- }
- }
-
-}
-
-extension TunnelsTableViewController: Identifyable {}
-
-class TunnelFetchedResultsControllerDelegate: NSObject, FetchedResultsControllerDelegate {
-
- private weak var tableView: UITableView?
- private var arrowImage: UIImageView?
-
- // MARK: - Lifecycle
- init(tableView: UITableView) {
- self.tableView = tableView
- }
-
- func fetchedResultsControllerDidPerformFetch(_ controller: FetchedResultsController) {
- tableView?.reloadData()
- updateEmptyIndicator(controller)
- }
-
- func fetchedResultsControllerWillChangeContent(_ controller: FetchedResultsController) {
- tableView?.beginUpdates()
- }
-
- func fetchedResultsControllerDidChangeContent(_ controller: FetchedResultsController) {
- tableView?.endUpdates()
- updateEmptyIndicator(controller)
- }
-
- func fetchedResultsController(_ controller: FetchedResultsController, didChangeObject change: FetchedResultsObjectChange) {
- guard let tableView = tableView else { return }
- switch change {
- case let .insert(_, indexPath):
- tableView.insertRows(at: [indexPath], with: .automatic)
-
- case let .delete(_, indexPath):
- tableView.deleteRows(at: [indexPath], with: .automatic)
-
- case let .move(_, fromIndexPath, toIndexPath):
- tableView.moveRow(at: fromIndexPath, to: toIndexPath)
-
- case let .update(_, indexPath):
- tableView.reloadRows(at: [indexPath], with: .automatic)
- }
- }
-
- func fetchedResultsController(_ controller: FetchedResultsController, didChangeSection change: FetchedResultsSectionChange) {
- guard let tableView = tableView else { return }
- switch change {
- case let .insert(_, index):
- tableView.insertSections(IndexSet(integer: index), with: .automatic)
-
- case let .delete(_, index):
- tableView.deleteSections(IndexSet(integer: index), with: .automatic)
- }
- }
-
- private func updateEmptyIndicator(_ controller: FetchedResultsController) {
- guard let tableView = tableView else { return }
- if controller.count > 0 {
- tableView.backgroundView = nil
- arrowImage = nil
- } else {
- if arrowImage == nil {
- let imageView = UIImageView(image: UIImage(named: "Arrow"))
- imageView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
- imageView.frame = tableView.bounds
- imageView.contentMode = .bottomRight
- tableView.backgroundView = imageView
- arrowImage = imageView
- }
- }
- }
-}
-
-protocol TunnelTableViewCellDelegate: class {
- func connect(tunnelIdentifier: String)
- func disconnect(tunnelIdentifier: String)
-}
-
-class TunnelTableViewCell: UITableViewCell {
-
- @IBOutlet weak var tunnelTitleLabel: UILabel!
- @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
- @IBOutlet weak var tunnelSwitch: UISwitch!
-
- weak var delegate: TunnelTableViewCellDelegate?
- private var tunnelIdentifier: String?
-
- @IBAction func tunnelSwitchChanged(_ sender: Any) {
- tunnelSwitch.isEnabled = false
- guard let tunnelIdentifier = tunnelIdentifier else {
- return
- }
-
- if tunnelSwitch.isOn {
- delegate?.connect(tunnelIdentifier: tunnelIdentifier)
- } else {
- delegate?.disconnect(tunnelIdentifier: tunnelIdentifier)
- }
- }
-
- func configure(tunnel: Tunnel, status: NEVPNStatus) {
- self.tunnelTitleLabel?.text = tunnel.title
- tunnelIdentifier = tunnel.tunnelIdentifier
-
- if status == .connecting || status == .disconnecting || status == .reasserting {
- activityIndicator.startAnimating()
- tunnelSwitch.isHidden = true
- } else {
- activityIndicator.stopAnimating()
- tunnelSwitch.isHidden = false
- }
-
- tunnelSwitch.isOn = status == .connected
- tunnelSwitch.onTintColor = status == .invalid || status == .reasserting ? .gray : .green
- tunnelSwitch.isEnabled = true
- }
-
- override func setEditing(_ editing: Bool, animated: Bool) {
- super.setEditing(editing, animated: animated)
- tunnelSwitch.isHidden = editing
- }
-}
-
-extension TunnelTableViewCell: Identifyable {}
diff --git a/WireGuard/ViewControllers/UITableView+WireGuard.swift b/WireGuard/ViewControllers/UITableView+WireGuard.swift
deleted file mode 100644
index a8b913b..0000000
--- a/WireGuard/ViewControllers/UITableView+WireGuard.swift
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import Foundation
-
-import UIKit
-
-extension UITableView {
-
- func register(type: T.Type, prefix: String = "") where T: UITableViewCell {
- register(type, forCellReuseIdentifier: prefix + type.identifier)
- }
-
- func dequeueReusableCell(type: T.Type, for indexPath: IndexPath, prefix: String = "") -> T where T: UITableViewCell {
- return dequeueReusableCell(withIdentifier: prefix + type.identifier, for: indexPath) as! T // swiftlint:disable:this force_cast
- }
-
- func registerNib(type: T.Type, prefix: String = "") where T: UITableViewCell {
- let nib = UINib(nibName: prefix + type.identifier, bundle: nil)
- register(nib, forCellReuseIdentifier: prefix + type.identifier)
- }
-
- func registerNib(type: T.Type, prefix: String = "") where T: UITableViewHeaderFooterView {
- let nib = UINib(nibName: prefix + type.identifier, bundle: nil)
- register(nib, forHeaderFooterViewReuseIdentifier: prefix + type.identifier)
- }
-
- func dequeueReusableHeaderFooterView(type: T.Type, prefix: String = "") -> T where T: UITableViewHeaderFooterView {
- return dequeueReusableHeaderFooterView(withIdentifier: prefix + type.identifier) as! T // swiftlint:disable:this force_cast
- }
-}
diff --git a/WireGuard/WireGuard-Bridging-Header.h b/WireGuard/WireGuard-Bridging-Header.h
deleted file mode 100644
index 95922cc..0000000
--- a/WireGuard/WireGuard-Bridging-Header.h
+++ /dev/null
@@ -1,6 +0,0 @@
-//
-// Use this file to import your target's public headers that you would like to expose to Swift.
-//
-
-#import "Crypto/x25519.h"
-#import "../wireguard-go-bridge/wireguard.h"
diff --git a/WireGuard/WireGuard.entitlements b/WireGuard/WireGuard.entitlements
deleted file mode 100644
index a4774c6..0000000
--- a/WireGuard/WireGuard.entitlements
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
- com.apple.developer.networking.networkextension
-
- packet-tunnel-provider
-
- com.apple.security.application-groups
-
- group.com.wireguard.ios
-
- keychain-access-groups
-
- $(AppIdentifierPrefix)com.wireguard.ios
-
-
-
diff --git a/WireGuardTests/Info.plist b/WireGuardTests/Info.plist
deleted file mode 100644
index 6c40a6c..0000000
--- a/WireGuardTests/Info.plist
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- BNDL
- CFBundleShortVersionString
- 1.0
- CFBundleVersion
- 1
-
-
diff --git a/WireGuardTests/ValidatorsTests.swift b/WireGuardTests/ValidatorsTests.swift
deleted file mode 100644
index 39acd06..0000000
--- a/WireGuardTests/ValidatorsTests.swift
+++ /dev/null
@@ -1,189 +0,0 @@
-//
-// Copyright © 2018 WireGuard LLC. All rights reserved.
-//
-
-import XCTest
-@testable import WireGuard
-
-class ValidatorsTests: XCTestCase {
- func testEndpoint() throws {
- _ = try Endpoint(endpointString: "[2607:f938:3001:4000::aac]:12345")
- _ = try Endpoint(endpointString: "192.168.0.1:12345")
- }
-
- func testEndpoint_invalidIP() throws {
- func executeTest(endpointString: String, ipString: String, file: StaticString = #file, line: UInt = #line) {
- XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in
- guard case EndpointValidationError.invalidIP(let value) = error else {
- return XCTFail("Unexpected error: \(error)", file: file, line: line)
- }
- XCTAssertEqual(value, ipString, file: file, line: line)
- }
- }
-
- executeTest(endpointString: "12345:12345", ipString: "12345")
- executeTest(endpointString: ":12345", ipString: "")
- }
-
- func testEndpoint_invalidPort() throws {
- func executeTest(endpointString: String, portString: String, file: StaticString = #file, line: UInt = #line) {
- XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in
- guard case EndpointValidationError.invalidPort(let value) = error else {
- return XCTFail("Unexpected error: \(error)", file: file, line: line)
- }
- XCTAssertEqual(value, portString, file: file, line: line)
- }
- }
-
- executeTest(endpointString: ":", portString: "")
- executeTest(endpointString: "[2607:f938:3001:4000::aac]:-12345", portString: "-12345")
- executeTest(endpointString: "[2607:f938:3001:4000::aac]", portString: "aac]")
- executeTest(endpointString: "[2607:f938:3001:4000::aac]:", portString: "")
- executeTest(endpointString: "192.168.0.1:-12345", portString: "-12345")
- executeTest(endpointString: "192.168.0.1:", portString: "")
-
- }
-
- func testEndpoint_noIpAndPort() throws {
-
- func executeTest(endpointString: String, file: StaticString = #file, line: UInt = #line) {
- XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in
- guard case EndpointValidationError.noIpAndPort(let value) = error else {
- return XCTFail("Unexpected error: \(error)", file: file, line: line)
- }
- XCTAssertEqual(value, endpointString, file: file, line: line)
- }
- }
-
- executeTest(endpointString: "192.168.0.1")
- executeTest(endpointString: "12345")
- }
-
- func testCIDRAddress() throws {
- _ = try CIDRAddress(stringRepresentation: "2607:f938:3001:4000::aac/24")
- _ = try CIDRAddress(stringRepresentation: "192.168.0.1/24")
- }
-
- func testIPv4CIDRAddress() throws {
- _ = try CIDRAddress(stringRepresentation: "192.168.0.1/24")
- }
-
- func testCIDRAddress_invalidIP() throws {
- func executeTest(stringRepresentation: String, ipString: String, file: StaticString = #file, line: UInt = #line) {
- XCTAssertThrowsError(try CIDRAddress(stringRepresentation: stringRepresentation)) { (error) in
- guard case CIDRAddressValidationError.invalidIP(let value) = error else {
- return XCTFail("Unexpected error: \(error)", file: file, line: line)
- }
- XCTAssertEqual(value, ipString, file: file, line: line)
- }
- }
-
- executeTest(stringRepresentation: "12345/12345", ipString: "12345")
- executeTest(stringRepresentation: "/12345", ipString: "")
- }
-
- func testCIDRAddress_invalidSubnet() throws {
- func executeTest(stringRepresentation: String, subnetString: String, file: StaticString = #file, line: UInt = #line) {
- XCTAssertThrowsError(try CIDRAddress(stringRepresentation: stringRepresentation)) { (error) in
- guard case CIDRAddressValidationError.invalidSubnet(let value) = error else {
- return XCTFail("Unexpected error: \(error)", file: file, line: line)
- }
- XCTAssertEqual(value, subnetString, file: file, line: line)
- }
- }
-
- executeTest(stringRepresentation: "/", subnetString: "")
- executeTest(stringRepresentation: "2607:f938:3001:4000::aac/a", subnetString: "a")
- executeTest(stringRepresentation: "2607:f938:3001:4000:/aac", subnetString: "aac")
- executeTest(stringRepresentation: "2607:f938:3001:4000::aac/", subnetString: "")
- executeTest(stringRepresentation: "192.168.0.1/a", subnetString: "a")
- executeTest(stringRepresentation: "192.168.0.1/", subnetString: "")
-
- }
-
- func testCIDRAddress_noIpAndSubnet() throws {
-
- func executeTest(stringRepresentation: String, file: StaticString = #file, line: UInt = #line) {
- XCTAssertThrowsError(try CIDRAddress(stringRepresentation: stringRepresentation)) { (error) in
- guard case CIDRAddressValidationError.noIpAndSubnet(let value) = error else {
- return XCTFail("Unexpected error: \(error)", file: file, line: line)
- }
- XCTAssertEqual(value, stringRepresentation, file: file, line: line)
- }
- }
-
- executeTest(stringRepresentation: "192.168.0.1")
- executeTest(stringRepresentation: "12345")
- }
-
- // swiftlint:disable next function_body_length
- func testIPv4CIDRAddressSubnetConversion() throws {
- // swiftlint:disable force_try
- let cidrAddress1 = try! CIDRAddress(stringRepresentation: "128.0.0.0/1")!
- XCTAssertEqual(cidrAddress1.ipAddress, cidrAddress1.subnetString)
- let cidrAddress2 = try! CIDRAddress(stringRepresentation: "192.0.0.0/2")!
- XCTAssertEqual(cidrAddress2.ipAddress, cidrAddress2.subnetString)
- let cidrAddress3 = try! CIDRAddress(stringRepresentation: "224.0.0.0/3")!
- XCTAssertEqual(cidrAddress3.ipAddress, cidrAddress3.subnetString)
- let cidrAddress4 = try! CIDRAddress(stringRepresentation: "240.0.0.0/4")!
- XCTAssertEqual(cidrAddress4.ipAddress, cidrAddress4.subnetString)
- let cidrAddress5 = try! CIDRAddress(stringRepresentation: "248.0.0.0/5")!
- XCTAssertEqual(cidrAddress5.ipAddress, cidrAddress5.subnetString)
- let cidrAddress6 = try! CIDRAddress(stringRepresentation: "252.0.0.0/6")!
- XCTAssertEqual(cidrAddress6.ipAddress, cidrAddress6.subnetString)
- let cidrAddress7 = try! CIDRAddress(stringRepresentation: "254.0.0.0/7")!
- XCTAssertEqual(cidrAddress7.ipAddress, cidrAddress7.subnetString)
- let cidrAddress8 = try! CIDRAddress(stringRepresentation: "255.0.0.0/8")!
- XCTAssertEqual(cidrAddress8.ipAddress, cidrAddress8.subnetString)
- let cidrAddress9 = try! CIDRAddress(stringRepresentation: "255.128.0.0/9")!
- XCTAssertEqual(cidrAddress9.ipAddress, cidrAddress9.subnetString)
- let cidrAddress10 = try! CIDRAddress(stringRepresentation: "255.192.0.0/10")!
- XCTAssertEqual(cidrAddress10.ipAddress, cidrAddress10.subnetString)
- let cidrAddress11 = try! CIDRAddress(stringRepresentation: "255.224.0.0/11")!
- XCTAssertEqual(cidrAddress11.ipAddress, cidrAddress11.subnetString)
- let cidrAddress12 = try! CIDRAddress(stringRepresentation: "255.240.0.0/12")!
- XCTAssertEqual(cidrAddress12.ipAddress, cidrAddress12.subnetString)
- let cidrAddress13 = try! CIDRAddress(stringRepresentation: "255.248.0.0/13")!
- XCTAssertEqual(cidrAddress13.ipAddress, cidrAddress13.subnetString)
- let cidrAddress14 = try! CIDRAddress(stringRepresentation: "255.252.0.0/14")!
- XCTAssertEqual(cidrAddress14.ipAddress, cidrAddress14.subnetString)
- let cidrAddress15 = try! CIDRAddress(stringRepresentation: "255.254.0.0/15")!
- XCTAssertEqual(cidrAddress15.ipAddress, cidrAddress15.subnetString)
- let cidrAddress16 = try! CIDRAddress(stringRepresentation: "255.255.0.0/16")!
- XCTAssertEqual(cidrAddress16.ipAddress, cidrAddress16.subnetString)
- let cidrAddress17 = try! CIDRAddress(stringRepresentation: "255.255.128.0/17")!
- XCTAssertEqual(cidrAddress17.ipAddress, cidrAddress17.subnetString)
- let cidrAddress18 = try! CIDRAddress(stringRepresentation: "255.255.192.0/18")!
- XCTAssertEqual(cidrAddress18.ipAddress, cidrAddress18.subnetString)
- let cidrAddress19 = try! CIDRAddress(stringRepresentation: "255.255.224.0/19")!
- XCTAssertEqual(cidrAddress19.ipAddress, cidrAddress19.subnetString)
- let cidrAddress20 = try! CIDRAddress(stringRepresentation: "255.255.240.0/20")!
- XCTAssertEqual(cidrAddress20.ipAddress, cidrAddress20.subnetString)
- let cidrAddress21 = try! CIDRAddress(stringRepresentation: "255.255.248.0/21")!
- XCTAssertEqual(cidrAddress21.ipAddress, cidrAddress21.subnetString)
- let cidrAddress22 = try! CIDRAddress(stringRepresentation: "255.255.252.0/22")!
- XCTAssertEqual(cidrAddress22.ipAddress, cidrAddress22.subnetString)
- let cidrAddress23 = try! CIDRAddress(stringRepresentation: "255.255.254.0/23")!
- XCTAssertEqual(cidrAddress23.ipAddress, cidrAddress23.subnetString)
- let cidrAddress24 = try! CIDRAddress(stringRepresentation: "255.255.255.0/24")!
- XCTAssertEqual(cidrAddress24.ipAddress, cidrAddress24.subnetString)
- let cidrAddress25 = try! CIDRAddress(stringRepresentation: "255.255.255.128/25")!
- XCTAssertEqual(cidrAddress25.ipAddress, cidrAddress25.subnetString)
- let cidrAddress26 = try! CIDRAddress(stringRepresentation: "255.255.255.192/26")!
- XCTAssertEqual(cidrAddress26.ipAddress, cidrAddress26.subnetString)
- let cidrAddress27 = try! CIDRAddress(stringRepresentation: "255.255.255.224/27")!
- XCTAssertEqual(cidrAddress27.ipAddress, cidrAddress27.subnetString)
- let cidrAddress28 = try! CIDRAddress(stringRepresentation: "255.255.255.240/28")!
- XCTAssertEqual(cidrAddress28.ipAddress, cidrAddress28.subnetString)
- let cidrAddress29 = try! CIDRAddress(stringRepresentation: "255.255.255.248/29")!
- XCTAssertEqual(cidrAddress29.ipAddress, cidrAddress29.subnetString)
- let cidrAddress30 = try! CIDRAddress(stringRepresentation: "255.255.255.252/30")!
- XCTAssertEqual(cidrAddress30.ipAddress, cidrAddress30.subnetString)
- let cidrAddress31 = try! CIDRAddress(stringRepresentation: "255.255.255.254/31")!
- XCTAssertEqual(cidrAddress31.ipAddress, cidrAddress31.subnetString)
- let cidrAddress32 = try! CIDRAddress(stringRepresentation: "255.255.255.255/32")!
- XCTAssertEqual(cidrAddress32.ipAddress, cidrAddress32.subnetString)
- // swiftlint:enable force_try
- }
-
-}