Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 24575a5cf9 | |||
| 34a8d70a45 | |||
| 733c29021e | |||
| f102051e22 | |||
| e228ac9d99 | |||
| 8860abc89e | |||
| 03cce06292 | |||
| a08a9ba4c4 | |||
| 8ec38e1d2b |
@@ -751,6 +751,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuard/WireGuard-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -770,6 +771,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuard/WireGuard-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
VERSION_NAME = 0.0.20181104
|
||||
VERSION_ID = 1
|
||||
VERSION_ID = 2
|
||||
|
||||
@@ -114,7 +114,12 @@ class WgQuickConfigFileParser {
|
||||
// Line contains an attribute
|
||||
let key = line[..<equalsIndex].trimmingCharacters(in: .whitespaces)
|
||||
let value = line[line.index(equalsIndex, offsetBy: 1)...].trimmingCharacters(in: .whitespaces)
|
||||
attributes[key] = value
|
||||
let keysWithMultipleEntriesAllowed: Set<String> = ["Address", "AllowedIPs", "DNS"]
|
||||
if let presentValue = attributes[key], keysWithMultipleEntriesAllowed.contains(key) {
|
||||
attributes[key] = presentValue + "," + value
|
||||
} else {
|
||||
attributes[key] = value
|
||||
}
|
||||
} else {
|
||||
if (lowercasedLine != "[interface]" && lowercasedLine != "[peer]") {
|
||||
throw ParseError.invalidLine(line)
|
||||
|
||||
@@ -96,6 +96,10 @@ class TunnelViewModel {
|
||||
}
|
||||
|
||||
func save() -> SaveResult<InterfaceConfiguration> {
|
||||
if let validatedConfiguration = validatedConfiguration {
|
||||
// It's already validated and saved
|
||||
return .saved(validatedConfiguration)
|
||||
}
|
||||
fieldsWithError.removeAll()
|
||||
guard let name = scratchpad[.name]?.trimmingCharacters(in: .whitespacesAndNewlines), (!name.isEmpty) else {
|
||||
fieldsWithError.insert(.name)
|
||||
@@ -234,6 +238,10 @@ class TunnelViewModel {
|
||||
}
|
||||
|
||||
func save() -> SaveResult<PeerConfiguration> {
|
||||
if let validatedConfiguration = validatedConfiguration {
|
||||
// It's already validated and saved
|
||||
return .saved(validatedConfiguration)
|
||||
}
|
||||
fieldsWithError.removeAll()
|
||||
guard let publicKeyString = scratchpad[.publicKey] else {
|
||||
fieldsWithError.insert(.publicKey)
|
||||
|
||||
@@ -11,7 +11,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
var mainVC: MainViewController?
|
||||
|
||||
func application(_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
|
||||
let window = UIWindow(frame: UIScreen.main.bounds)
|
||||
window.backgroundColor = UIColor.white
|
||||
@@ -26,7 +26,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
return true
|
||||
}
|
||||
|
||||
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
|
||||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
||||
defer {
|
||||
do {
|
||||
try FileManager.default.removeItem(at: url)
|
||||
|
||||
@@ -14,7 +14,7 @@ class CopyableLabelTableViewCell: UITableViewCell {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
|
||||
self.addGestureRecognizer(gestureRecognizer)
|
||||
|
||||
@@ -21,8 +21,6 @@ class ErrorPresenter {
|
||||
return ("Unable to remove tunnel", "Internal error")
|
||||
|
||||
// TunnelActivationError
|
||||
case TunnelActivationError.noEndpoint:
|
||||
return ("Endpoint missing", "There must be at least one peer with an endpoint")
|
||||
case TunnelActivationError.dnsResolutionFailed:
|
||||
return ("DNS resolution failure", "One or more endpoint domains could not be resolved")
|
||||
case TunnelActivationError.tunnelActivationFailed:
|
||||
|
||||
@@ -114,7 +114,9 @@ class QRScanViewController: UIViewController {
|
||||
|
||||
let alert = UIAlertController(title: NSLocalizedString("Please name the scanned tunnel", comment: ""), message: nil, preferredStyle: .alert)
|
||||
alert.addTextField(configurationHandler: nil)
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: nil))
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .cancel, handler: { [weak self] _ in
|
||||
self?.dismiss(animated: true, completion: nil)
|
||||
}))
|
||||
alert.addAction(UIAlertAction(title: NSLocalizedString("Save", comment: ""), style: .default, handler: { [weak self] _ in
|
||||
let title = alert.textFields?[0].text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
if (title.isEmpty) { return }
|
||||
|
||||
@@ -47,15 +47,15 @@ class SettingsTableViewController: UITableViewController {
|
||||
logo.frame = CGRect(x: 0, y: 0, width: width, height: height)
|
||||
logo.bounds = logo.frame.insetBy(dx: 2, dy: 2)
|
||||
self.tableView.tableFooterView = logo
|
||||
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
guard let logo = self.tableView.tableFooterView else { return }
|
||||
let fullHeight = max(self.tableView.contentSize.height, self.tableView.bounds.size.height - self.tableView.layoutMargins.top)
|
||||
let bottomPadding = max(self.tableView.layoutMargins.bottom, CGFloat(10))
|
||||
let fullHeight = max(self.tableView.contentSize.height, self.tableView.bounds.size.height - self.tableView.layoutMargins.top - bottomPadding)
|
||||
let e = logo.frame
|
||||
let padding = CGFloat(10)
|
||||
logo.frame = CGRect(x: e.minX, y: fullHeight - e.height - padding, width: e.width, height: e.height)
|
||||
logo.frame = CGRect(x: e.minX, y: fullHeight - e.height, width: e.width, height: e.height)
|
||||
}
|
||||
|
||||
@objc func doneTapped() {
|
||||
@@ -172,7 +172,7 @@ class TunnelSettingsTableViewKeyValueCell: UITableViewCell {
|
||||
set(value) { detailTextLabel?.text = value }
|
||||
}
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: .value1, reuseIdentifier: TunnelSettingsTableViewKeyValueCell.id)
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ class TunnelSettingsTableViewButtonCell: UITableViewCell {
|
||||
|
||||
let button: UIButton
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
button = UIButton(type: .system)
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
contentView.addSubview(button)
|
||||
|
||||
@@ -227,7 +227,7 @@ class TunnelDetailTableViewStatusCell: UITableViewCell {
|
||||
let statusSwitch: UISwitch
|
||||
private var statusObservervationToken: AnyObject?
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
statusSwitch = UISwitch()
|
||||
super.init(style: .default, reuseIdentifier: TunnelDetailTableViewKeyValueCell.id)
|
||||
accessoryView = statusSwitch
|
||||
@@ -308,7 +308,7 @@ class TunnelDetailTableViewKeyValueCell: CopyableLabelTableViewCell {
|
||||
let valueLabel: UILabel
|
||||
let valueScroller: UIScrollView
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
keyLabel = UILabel()
|
||||
valueLabel = UILabel()
|
||||
valueScroller = UIScrollView()
|
||||
@@ -387,7 +387,7 @@ class TunnelDetailTableViewButtonCell: UITableViewCell {
|
||||
let button: UIButton
|
||||
var buttonStandardTintColor: UIColor
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
button = UIButton(type: .system)
|
||||
buttonStandardTintColor = button.tintColor
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
@@ -448,7 +448,7 @@ class TunnelEditTableViewKeyValueCell: CopyableLabelTableViewCell {
|
||||
|
||||
private var textFieldValueOnBeginEditing: String = ""
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
keyLabel = UILabel()
|
||||
valueTextField = UITextField()
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
@@ -539,7 +539,7 @@ class TunnelEditTableViewButtonCell: UITableViewCell {
|
||||
let button: UIButton
|
||||
var buttonStandardTintColor: UIColor
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
button = UIButton(type: .system)
|
||||
buttonStandardTintColor = button.tintColor
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
@@ -590,7 +590,7 @@ class TunnelEditTableViewSwitchCell: UITableViewCell {
|
||||
|
||||
let switchView: UISwitch
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
switchView = UISwitch()
|
||||
super.init(style: .default, reuseIdentifier: reuseIdentifier)
|
||||
accessoryView = switchView
|
||||
|
||||
@@ -25,7 +25,7 @@ class TunnelsListTableViewController: UIViewController {
|
||||
self.navigationItem.leftBarButtonItem = settingsButtonItem
|
||||
|
||||
// Set up the busy indicator
|
||||
let busyIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
||||
let busyIndicator = UIActivityIndicatorView(style: .gray)
|
||||
busyIndicator.hidesWhenStopped = true
|
||||
|
||||
// Add the busyIndicator, centered
|
||||
@@ -386,9 +386,9 @@ class TunnelsListTableViewCell: UITableViewCell {
|
||||
private var statusObservervationToken: AnyObject?
|
||||
private var nameObservervationToken: AnyObject?
|
||||
|
||||
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
nameLabel = UILabel()
|
||||
busyIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
||||
busyIndicator = UIActivityIndicatorView(style: .gray)
|
||||
busyIndicator.hidesWhenStopped = true
|
||||
statusSwitch = UISwitch()
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
@@ -48,19 +48,23 @@ class PacketTunnelOptionsGenerator {
|
||||
|
||||
// Remote address
|
||||
|
||||
let remoteAddress: String
|
||||
if let firstEndpoint = resolvedEndpoints.compactMap({ $0 }).first {
|
||||
switch (firstEndpoint.host) {
|
||||
/* iOS requires a tunnel endpoint, whereas in WireGuard it's valid for
|
||||
* a tunnel to have no endpoint, or for there to be many endpoints, in
|
||||
* which case, displaying a single one in settings doesn't really
|
||||
* make sense. So, we fill it in with this placeholder, which is not
|
||||
* a valid IP address that will actually route over the Internet.
|
||||
*/
|
||||
var remoteAddress: String = "0.0.0.0"
|
||||
let endpointsCompact = resolvedEndpoints.compactMap({ $0 })
|
||||
if endpointsCompact.count == 1 {
|
||||
switch (endpointsCompact.first!.host) {
|
||||
case .ipv4(let address):
|
||||
remoteAddress = "\(address)"
|
||||
case .ipv6(let address):
|
||||
remoteAddress = "\(address)"
|
||||
default:
|
||||
fatalError("Endpoint must be resolved")
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// We don't have any peer with an endpoint
|
||||
remoteAddress = ""
|
||||
}
|
||||
|
||||
options[.remoteAddress] = remoteAddress as NSObject
|
||||
|
||||
@@ -13,7 +13,6 @@ protocol TunnelsManagerDelegate: class {
|
||||
}
|
||||
|
||||
enum TunnelActivationError: Error {
|
||||
case noEndpoint
|
||||
case dnsResolutionFailed
|
||||
case tunnelActivationFailed
|
||||
case attemptingActivationWhenAnotherTunnelIsBusy(otherTunnelStatus: TunnelStatus)
|
||||
@@ -214,14 +213,20 @@ extension NETunnelProviderProtocol {
|
||||
self.init()
|
||||
|
||||
let appId = Bundle.main.bundleIdentifier!
|
||||
let firstValidEndpoint = tunnelConfiguration.peers.first(where: { $0.endpoint != nil })?.endpoint
|
||||
|
||||
providerBundleIdentifier = "\(appId).network-extension"
|
||||
providerConfiguration = [
|
||||
"tunnelConfiguration": serializedTunnelConfiguration,
|
||||
"tunnelConfigurationVersion": 1
|
||||
]
|
||||
serverAddress = firstValidEndpoint?.stringRepresentation() ?? "Unspecified"
|
||||
|
||||
let endpoints = tunnelConfiguration.peers.compactMap({$0.endpoint})
|
||||
if endpoints.count == 1 {
|
||||
serverAddress = endpoints.first!.stringRepresentation()
|
||||
} else if endpoints.isEmpty {
|
||||
serverAddress = "Unspecified"
|
||||
} else {
|
||||
serverAddress = "Multiple endpoints"
|
||||
}
|
||||
username = tunnelConfiguration.interface.name
|
||||
}
|
||||
|
||||
@@ -262,15 +267,6 @@ class TunnelContainer: NSObject {
|
||||
guard let tunnelConfiguration = tunnelConfiguration() else { fatalError() }
|
||||
let endpoints = tunnelConfiguration.peers.map { $0.endpoint }
|
||||
|
||||
// Ensure there's a tunner server address we can give to iOS
|
||||
guard (endpoints.contains(where: { $0 != nil })) else {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.status = .inactive
|
||||
completionHandler(TunnelActivationError.noEndpoint)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve DNS and start the tunnel
|
||||
let dnsResolver = DNSResolver(endpoints: endpoints)
|
||||
let resolvedEndpoints = dnsResolver.resolveWithoutNetworkRequests()
|
||||
|
||||
@@ -92,7 +92,13 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||
networkSettings.ipv4Settings = ipv4Settings
|
||||
|
||||
// IPv6 settings
|
||||
let ipv6Settings = NEIPv6Settings(addresses: ipv6Addresses, networkPrefixLengths: ipv6NetworkPrefixLengths)
|
||||
|
||||
/* Big fat ugly hack for broken iOS networking stack: the smallest prefix that will have
|
||||
* any effect on iOS is a /120, so we clamp everything above to /120. This is potentially
|
||||
* very bad, if various network parameters were actually relying on that subnet being
|
||||
* intentionally small. TODO: talk about this with upstream iOS devs.
|
||||
*/
|
||||
let ipv6Settings = NEIPv6Settings(addresses: ipv6Addresses, networkPrefixLengths: ipv6NetworkPrefixLengths.map { NSNumber(value: min(120, $0.intValue)) })
|
||||
assert(ipv6IncludedRouteAddresses.count == ipv6IncludedRouteNetworkPrefixLengths.count)
|
||||
ipv6Settings.includedRoutes = zip(ipv6IncludedRouteAddresses, ipv6IncludedRouteNetworkPrefixLengths).map {
|
||||
NEIPv6Route(destinationAddress: $0.0, networkPrefixLength: $0.1)
|
||||
|
||||
@@ -28,7 +28,7 @@ version-header: $(DESTDIR)/wireguard-go-version.h
|
||||
|
||||
GOBUILDARCH := $(GOARCH_$(shell uname -m))
|
||||
GOBUILDOS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
|
||||
GOBUILDVERSION := 1.11.1
|
||||
GOBUILDVERSION := 1.11.2
|
||||
GOBUILDTARBALL := https://dl.google.com/go/go$(GOBUILDVERSION).$(GOBUILDOS)-$(GOBUILDARCH).tar.gz
|
||||
GOBUILDVERSION_NEEDED := go version go$(GOBUILDVERSION) $(GOBUILDOS)/$(GOBUILDARCH)
|
||||
export GOROOT := $(BUILDDIR)/goroot
|
||||
@@ -68,7 +68,7 @@ $(BUILDDIR)/libwg-go-$(1).a: $(BUILDDIR)/.prepared
|
||||
CGO_CFLAGS="$(CGO_FLAGS_$(1))" \
|
||||
CGO_LDFLAGS="$(CGO_FLAGS_$(1))" \
|
||||
GOARCH="$(GOARCH_$(1))" \
|
||||
go build -tags ios -v -o "$(BUILDDIR)/libwg-go-$(1).a" -buildmode c-archive && go version > "$(BUILDDIR)/.gobuildversion"; \
|
||||
go build -tags ios -ldflags=-w -v -o "$(BUILDDIR)/libwg-go-$(1).a" -buildmode c-archive && go version > "$(BUILDDIR)/.gobuildversion"; \
|
||||
ret=$$$$?; \
|
||||
rm -f "$(BUILDDIR)/libwg-go-$(1).h"; \
|
||||
exit $$$$ret
|
||||
|
||||
Reference in New Issue
Block a user