Compare commits

..

9 Commits

Author SHA1 Message Date
Jason A. Donenfeld 24575a5cf9 Version bump
We update the build number, not the version number, so that test flight
doesn't need a new review.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-11-05 21:44:00 +01:00
Roopesh Chander 34a8d70a45 Parser: Address, DNS and AllowedIPs can have mutliple entries
Signed-off-by: Roopesh Chander <roop@roopc.net>
2018-11-05 23:53:00 +05:30
Roopesh Chander 733c29021e QR Code: Dismiss the QR code screen when the name prompt is cancelled
Signed-off-by: Roopesh Chander <roop@roopc.net>
2018-11-05 23:38:41 +05:30
Roopesh Chander f102051e22 Tunnel view model: No need to save if we already have a validated configuration object
Signed-off-by: Roopesh Chander <roop@roopc.net>
2018-11-05 22:55:09 +05:30
Jason A. Donenfeld e228ac9d99 global: convert to Swift 4.2
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-11-05 06:31:25 +01:00
Jason A. Donenfeld 8860abc89e TunnelsManager: account for no or many endpoints
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-11-05 06:23:26 +01:00
Jason A. Donenfeld 03cce06292 wireguard-go-bridge: work around DWARF generation issue
Golang bug 25148 upstream.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-11-05 04:47:11 +01:00
Jason A. Donenfeld a08a9ba4c4 PacketTunnelProvider: clamp v6 addresses to /120
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-11-05 03:11:11 +01:00
Jason A. Donenfeld 8ec38e1d2b Settings: account for bottom padding on iPhone X
Reported-by: Jeffrey A. Donenfeld <jad@runblue.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2018-11-05 02:09:40 +01:00
16 changed files with 67 additions and 46 deletions
@@ -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 -1
View File
@@ -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)
+2 -2
View File
@@ -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
+9 -13
View File
@@ -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)
+2 -2
View File
@@ -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