summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-08-13 13:59:11 +0300
committerAndrej Mihajlov <and@mullvad.net>2019-08-16 12:50:07 +0300
commitd9e1776ae310c2b1d4b5cf6627f05530afcc0e95 (patch)
treeaab9aea4e022d3fd8436faea50dc8d50a0e955c0
parent3605029f6f78b6ad43d6af0537ac1cb4c6190202 (diff)
downloadmullvadvpn-d9e1776ae310c2b1d4b5cf6627f05530afcc0e95.tar.xz
mullvadvpn-d9e1776ae310c2b1d4b5cf6627f05530afcc0e95.zip
Add wireguard related API methods
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj42
-rw-r--r--ios/MullvadVPN/IPAddressRange.swift92
-rw-r--r--ios/MullvadVPN/IpAddress+Codable.swift47
-rw-r--r--ios/MullvadVPN/JsonRequestProcedure.swift (renamed from ios/MullvadVPN/JSONRequestProcedure.swift)13
-rw-r--r--ios/MullvadVPN/JsonRpc.swift36
-rw-r--r--ios/MullvadVPN/MullvadAPI.swift42
-rw-r--r--ios/MullvadVPN/ProcedureKit+Patches.swift49
-rw-r--r--ios/MullvadVPN/WireguardAssociatedAddresses.swift15
8 files changed, 305 insertions, 31 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 8b44ec32f3..df975f7b3c 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -16,12 +16,16 @@
582BB1B1229569620055B6EF /* CustomNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582BB1B0229569620055B6EF /* CustomNavigationBar.swift */; };
582BB1B3229574F40055B6EF /* SettingsAccountCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582BB1B2229574F40055B6EF /* SettingsAccountCell.swift */; };
582BB1B52295780F0055B6EF /* AccountExpiry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582BB1B42295780F0055B6EF /* AccountExpiry.swift */; };
+ 5840250122B1124600E4CFEC /* IpAddress+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840250022B1124600E4CFEC /* IpAddress+Codable.swift */; };
+ 5840250222B1124600E4CFEC /* IpAddress+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5840250022B1124600E4CFEC /* IpAddress+Codable.swift */; };
58461AD3228D622E00B72ECB /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58461AD2228D622E00B72ECB /* Account.swift */; };
58535B85229E89E7004BCBBD /* WeakBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58535B84229E89E7004BCBBD /* WeakBox.swift */; };
5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */; };
5867A51C2248F26A005513C0 /* SegueIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5867A51B2248F26A005513C0 /* SegueIdentifier.swift */; };
58723E7522A54CB2009837F5 /* libwg-go.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58723E7422A54C63009837F5 /* libwg-go.a */; };
587425C12299833500CA2045 /* RootContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587425C02299833500CA2045 /* RootContainerViewController.swift */; };
+ 58781CC622AE5F4B009B9D8E /* ProcedureKit+Patches.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58781CC522AE5F4B009B9D8E /* ProcedureKit+Patches.swift */; };
+ 58781CC722AE602B009B9D8E /* ProcedureKit+Patches.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58781CC522AE5F4B009B9D8E /* ProcedureKit+Patches.swift */; };
587B08E0229433EB000E6F17 /* LoginState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B08DF229433EB000E6F17 /* LoginState.swift */; };
587B08E2229460C1000E6F17 /* WebLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587B08E1229460C1000E6F17 /* WebLinks.swift */; };
587CBFE322807F530028DED3 /* UIColor+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587CBFE222807F530028DED3 /* UIColor+Helpers.swift */; };
@@ -34,7 +38,13 @@
58ADDB3C227B1BD200FAFEA7 /* JsonRpc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58ADDB3B227B1BD200FAFEA7 /* JsonRpc.swift */; };
58ADDB3E227B1CD900FAFEA7 /* MullvadAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58ADDB3D227B1CD900FAFEA7 /* MullvadAPI.swift */; };
58ADDB40227B1E7100FAFEA7 /* Optional+Unwrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58ADDB3F227B1E7100FAFEA7 /* Optional+Unwrap.swift */; };
+ 58B8743222B25A7600015324 /* WireguardAssociatedAddresses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B8743122B25A7600015324 /* WireguardAssociatedAddresses.swift */; };
+ 58BFA5C022A7C8A900A6173D /* MullvadAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58ADDB3D227B1CD900FAFEA7 /* MullvadAPI.swift */; };
+ 58BFA5C122A7C92400A6173D /* JsonRequestProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E30228B2AEB00C7710B /* JsonRequestProcedure.swift */; };
+ 58BFA5C222A7C92900A6173D /* JsonRpc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58ADDB3B227B1BD200FAFEA7 /* JsonRpc.swift */; };
58C3A4B222456F1B00340BDB /* AccountInputGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */; };
+ 58C6B34F22BB7AC0003C19AD /* IPAddressRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C6B34E22BB7AC0003C19AD /* IPAddressRange.swift */; };
+ 58C6B35122BB7CFD003C19AD /* IPAddressRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C6B34E22BB7AC0003C19AD /* IPAddressRange.swift */; };
58CCA010224249A1004F3011 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA00F224249A1004F3011 /* ConnectViewController.swift */; };
58CCA01222424D11004F3011 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA01122424D11004F3011 /* SettingsViewController.swift */; };
58CCA0162242560B004F3011 /* UIColor+Palette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CCA0152242560B004F3011 /* UIColor+Palette.swift */; };
@@ -47,7 +57,10 @@
58CE5E6E224146210008646E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 58CE5E6C224146210008646E /* LaunchScreen.storyboard */; };
58CE5E7C224146470008646E /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58CE5E7B224146470008646E /* PacketTunnelProvider.swift */; };
58CE5E81224146470008646E /* PacketTunnel.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 58CE5E79224146470008646E /* PacketTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
- 58F19E31228B2AEB00C7710B /* JSONRequestProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E30228B2AEB00C7710B /* JSONRequestProcedure.swift */; };
+ 58D06EA82302E1A1000C75C6 /* WireguardAssociatedAddresses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B8743122B25A7600015324 /* WireguardAssociatedAddresses.swift */; };
+ 58D06EA92302E1A8000C75C6 /* RelayList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5888AD88227B18C40051EB06 /* RelayList.swift */; };
+ 58D06EAA2302E1B0000C75C6 /* AccountVerificationProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E32228B383300C7710B /* AccountVerificationProcedure.swift */; };
+ 58F19E31228B2AEB00C7710B /* JsonRequestProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E30228B2AEB00C7710B /* JsonRequestProcedure.swift */; };
58F19E33228B383300C7710B /* AccountVerificationProcedure.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E32228B383300C7710B /* AccountVerificationProcedure.swift */; };
58F19E35228C15BA00C7710B /* SpinnerActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */; };
58F83F08229D3F560086FCE3 /* AccountExpiryRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F83F07229D3F560086FCE3 /* AccountExpiryRefresh.swift */; };
@@ -95,6 +108,7 @@
582BB1B0229569620055B6EF /* CustomNavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomNavigationBar.swift; sourceTree = "<group>"; };
582BB1B2229574F40055B6EF /* SettingsAccountCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsAccountCell.swift; sourceTree = "<group>"; };
582BB1B42295780F0055B6EF /* AccountExpiry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpiry.swift; sourceTree = "<group>"; };
+ 5840250022B1124600E4CFEC /* IpAddress+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IpAddress+Codable.swift"; sourceTree = "<group>"; };
58461AD2228D622E00B72ECB /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
58535B84229E89E7004BCBBD /* WeakBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakBox.swift; sourceTree = "<group>"; };
5862805322428EF100F5A6E1 /* TranslucentButtonBlurView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslucentButtonBlurView.swift; sourceTree = "<group>"; };
@@ -102,6 +116,7 @@
5867A51B2248F26A005513C0 /* SegueIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegueIdentifier.swift; sourceTree = "<group>"; };
58723E7422A54C63009837F5 /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; };
587425C02299833500CA2045 /* RootContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootContainerViewController.swift; sourceTree = "<group>"; };
+ 58781CC522AE5F4B009B9D8E /* ProcedureKit+Patches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcedureKit+Patches.swift"; sourceTree = "<group>"; };
587B08DF229433EB000E6F17 /* LoginState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginState.swift; sourceTree = "<group>"; };
587B08E1229460C1000E6F17 /* WebLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebLinks.swift; sourceTree = "<group>"; };
587CBFE222807F530028DED3 /* UIColor+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Helpers.swift"; sourceTree = "<group>"; };
@@ -114,7 +129,9 @@
58ADDB3B227B1BD200FAFEA7 /* JsonRpc.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonRpc.swift; sourceTree = "<group>"; };
58ADDB3D227B1CD900FAFEA7 /* MullvadAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MullvadAPI.swift; sourceTree = "<group>"; };
58ADDB3F227B1E7100FAFEA7 /* Optional+Unwrap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Optional+Unwrap.swift"; sourceTree = "<group>"; };
+ 58B8743122B25A7600015324 /* WireguardAssociatedAddresses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireguardAssociatedAddresses.swift; sourceTree = "<group>"; };
58C3A4B122456F1A00340BDB /* AccountInputGroupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountInputGroupView.swift; sourceTree = "<group>"; };
+ 58C6B34E22BB7AC0003C19AD /* IPAddressRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPAddressRange.swift; sourceTree = "<group>"; };
58CCA00F224249A1004F3011 /* ConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = "<group>"; };
58CCA01122424D11004F3011 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
58CCA0152242560B004F3011 /* UIColor+Palette.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Palette.swift"; sourceTree = "<group>"; };
@@ -131,7 +148,7 @@
58CE5E7B224146470008646E /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
58CE5E7D224146470008646E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
58CE5E7E224146470008646E /* PacketTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PacketTunnel.entitlements; sourceTree = "<group>"; };
- 58F19E30228B2AEB00C7710B /* JSONRequestProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONRequestProcedure.swift; sourceTree = "<group>"; };
+ 58F19E30228B2AEB00C7710B /* JsonRequestProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonRequestProcedure.swift; sourceTree = "<group>"; };
58F19E32228B383300C7710B /* AccountVerificationProcedure.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountVerificationProcedure.swift; sourceTree = "<group>"; };
58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinnerActivityIndicatorView.swift; sourceTree = "<group>"; };
58F83F07229D3F560086FCE3 /* AccountExpiryRefresh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountExpiryRefresh.swift; sourceTree = "<group>"; };
@@ -212,7 +229,9 @@
5894FC482296A8090017471D /* CustomButton.swift */,
582BB1B0229569620055B6EF /* CustomNavigationBar.swift */,
58CE5E6F224146210008646E /* Info.plist */,
- 58F19E30228B2AEB00C7710B /* JSONRequestProcedure.swift */,
+ 5840250022B1124600E4CFEC /* IpAddress+Codable.swift */,
+ 58C6B34E22BB7AC0003C19AD /* IPAddressRange.swift */,
+ 58F19E30228B2AEB00C7710B /* JsonRequestProcedure.swift */,
58ADDB3B227B1BD200FAFEA7 /* JsonRpc.swift */,
58CE5E6C224146210008646E /* LaunchScreen.storyboard */,
587B08DF229433EB000E6F17 /* LoginState.swift */,
@@ -221,6 +240,7 @@
58ADDB3D227B1CD900FAFEA7 /* MullvadAPI.swift */,
5866F39B2243B82D00168AE5 /* MullvadVPN.entitlements */,
58ADDB3F227B1E7100FAFEA7 /* Optional+Unwrap.swift */,
+ 58781CC522AE5F4B009B9D8E /* ProcedureKit+Patches.swift */,
5888AD88227B18C40051EB06 /* RelayList.swift */,
5888AD7E2279B6BF0051EB06 /* RelayStatusIndicatorView.swift */,
587425C02299833500CA2045 /* RootContainerViewController.swift */,
@@ -241,6 +261,7 @@
58535B84229E89E7004BCBBD /* WeakBox.swift */,
587B08E1229460C1000E6F17 /* WebLinks.swift */,
58FBDAAA22A52DC500EB69A3 /* MullvadVPN-Bridging-Header.h */,
+ 58B8743122B25A7600015324 /* WireguardAssociatedAddresses.swift */,
);
path = MullvadVPN;
sourceTree = "<group>";
@@ -508,6 +529,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 5840250122B1124600E4CFEC /* IpAddress+Codable.swift in Sources */,
582BB1B52295780F0055B6EF /* AccountExpiry.swift in Sources */,
582BB1B3229574F40055B6EF /* SettingsAccountCell.swift in Sources */,
58CCA010224249A1004F3011 /* ConnectViewController.swift in Sources */,
@@ -515,6 +537,7 @@
582BB1B1229569620055B6EF /* CustomNavigationBar.swift in Sources */,
58461AD3228D622E00B72ECB /* Account.swift in Sources */,
5888AD87227B17950051EB06 /* SelectLocationController.swift in Sources */,
+ 58781CC622AE5F4B009B9D8E /* ProcedureKit+Patches.swift in Sources */,
58F19E35228C15BA00C7710B /* SpinnerActivityIndicatorView.swift in Sources */,
58ADDB40227B1E7100FAFEA7 /* Optional+Unwrap.swift in Sources */,
58CCA0162242560B004F3011 /* UIColor+Palette.swift in Sources */,
@@ -524,7 +547,9 @@
587B08E2229460C1000E6F17 /* WebLinks.swift in Sources */,
58CCA01822426713004F3011 /* AccountViewController.swift in Sources */,
58ADDB3E227B1CD900FAFEA7 /* MullvadAPI.swift in Sources */,
+ 58B8743222B25A7600015324 /* WireguardAssociatedAddresses.swift in Sources */,
587B08E0229433EB000E6F17 /* LoginState.swift in Sources */,
+ 58C6B34F22BB7AC0003C19AD /* IPAddressRange.swift in Sources */,
582BB1AF229566420055B6EF /* SettingsCell.swift in Sources */,
58535B85229E89E7004BCBBD /* WeakBox.swift in Sources */,
5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */,
@@ -538,7 +563,7 @@
589AB4F7227B64450039131E /* BasicTableViewCell.swift in Sources */,
5888AD7F2279B6BF0051EB06 /* RelayStatusIndicatorView.swift in Sources */,
5867A51C2248F26A005513C0 /* SegueIdentifier.swift in Sources */,
- 58F19E31228B2AEB00C7710B /* JSONRequestProcedure.swift in Sources */,
+ 58F19E31228B2AEB00C7710B /* JsonRequestProcedure.swift in Sources */,
5894FC492296A8090017471D /* CustomButton.swift in Sources */,
58CCA01E2242787B004F3011 /* AccountTextField.swift in Sources */,
587425C12299833500CA2045 /* RootContainerViewController.swift in Sources */,
@@ -552,7 +577,16 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 58D06EAA2302E1B0000C75C6 /* AccountVerificationProcedure.swift in Sources */,
+ 58781CC722AE602B009B9D8E /* ProcedureKit+Patches.swift in Sources */,
+ 58D06EA92302E1A8000C75C6 /* RelayList.swift in Sources */,
+ 58D06EA82302E1A1000C75C6 /* WireguardAssociatedAddresses.swift in Sources */,
+ 58BFA5C222A7C92900A6173D /* JsonRpc.swift in Sources */,
+ 58C6B35122BB7CFD003C19AD /* IPAddressRange.swift in Sources */,
+ 58BFA5C122A7C92400A6173D /* JsonRequestProcedure.swift in Sources */,
+ 5840250222B1124600E4CFEC /* IpAddress+Codable.swift in Sources */,
58CE5E7C224146470008646E /* PacketTunnelProvider.swift in Sources */,
+ 58BFA5C022A7C8A900A6173D /* MullvadAPI.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/ios/MullvadVPN/IPAddressRange.swift b/ios/MullvadVPN/IPAddressRange.swift
new file mode 100644
index 0000000000..a8169877cb
--- /dev/null
+++ b/ios/MullvadVPN/IPAddressRange.swift
@@ -0,0 +1,92 @@
+//
+// IPAddressRange.swift
+// MullvadVPN
+//
+// Created by pronebird on 20/06/2019.
+// Copyright © 2019 Amagicom AB. All rights reserved.
+//
+
+import Foundation
+import Network
+
+struct IPAddressRange {
+ let address: IPAddress
+ var networkPrefixLength: UInt8
+}
+
+extension IPAddressRange: Equatable {
+ static func == (lhs: IPAddressRange, rhs: IPAddressRange) -> Bool {
+ return lhs.address.rawValue == rhs.address.rawValue &&
+ lhs.networkPrefixLength == rhs.networkPrefixLength
+ }
+}
+
+extension IPAddressRange: Hashable {
+ func hash(into hasher: inout Hasher) {
+ hasher.combine(address.rawValue)
+ hasher.combine(networkPrefixLength)
+ }
+}
+
+extension IPAddressRange: CustomStringConvertible {
+ var description: String {
+ return "\(address)/\(networkPrefixLength)"
+ }
+}
+
+extension IPAddressRange {
+
+ init?(from string: String) {
+ guard let parsed = IPAddressRange.parseAddressString(string) else { return nil }
+ address = parsed.0
+ networkPrefixLength = parsed.1
+ }
+
+ private static func parseAddressString(_ string: String) -> (IPAddress, UInt8)? {
+ let endOfIPAddress = string.lastIndex(of: "/") ?? string.endIndex
+ let addressString = String(string[string.startIndex ..< endOfIPAddress])
+ let address: IPAddress
+ if let addr = IPv4Address(addressString) {
+ address = addr
+ } else if let addr = IPv6Address(addressString) {
+ address = addr
+ } else {
+ return nil
+ }
+
+ let maxNetworkPrefixLength: UInt8 = address is IPv4Address ? 32 : 128
+ var networkPrefixLength: UInt8
+ if endOfIPAddress < string.endIndex { // "/" was located
+ let indexOfNetworkPrefixLength = string.index(after: endOfIPAddress)
+ guard indexOfNetworkPrefixLength < string.endIndex else { return nil }
+ let networkPrefixLengthSubstring = string[indexOfNetworkPrefixLength ..< string.endIndex]
+ guard let npl = UInt8(networkPrefixLengthSubstring) else { return nil }
+ networkPrefixLength = min(npl, maxNetworkPrefixLength)
+ } else {
+ networkPrefixLength = maxNetworkPrefixLength
+ }
+
+ return (address, networkPrefixLength)
+ }
+}
+
+extension IPAddressRange: Codable {
+
+ func encode(to encoder: Encoder) throws {
+ var container = encoder.singleValueContainer()
+
+ try container.encode("\(self)")
+ }
+
+ init(from decoder: Decoder) throws {
+ let container = try decoder.singleValueContainer()
+ let value = try container.decode(String.self)
+
+ if let addressRange = IPAddressRange(from: value) {
+ self = addressRange
+ } else {
+ throw DecodingError.dataCorruptedError(
+ in: container, debugDescription: "Invalid IPAddressRange representation")
+ }
+ }
+}
diff --git a/ios/MullvadVPN/IpAddress+Codable.swift b/ios/MullvadVPN/IpAddress+Codable.swift
new file mode 100644
index 0000000000..104aae7cdb
--- /dev/null
+++ b/ios/MullvadVPN/IpAddress+Codable.swift
@@ -0,0 +1,47 @@
+//
+// IpAddress+Codable.swift
+// MullvadVPN
+//
+// Created by pronebird on 12/06/2019.
+// Copyright © 2019 Amagicom AB. All rights reserved.
+//
+
+import Network
+
+extension IPv4Address: Codable {
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.singleValueContainer()
+ let ipString = try container.decode(String.self)
+
+ if let decoded = IPv4Address(ipString) {
+ self = decoded
+ } else {
+ throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid IPv4 representation")
+ }
+ }
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.singleValueContainer()
+
+ try container.encode(String(reflecting: self))
+ }
+}
+
+extension IPv6Address: Codable {
+ public init(from decoder: Decoder) throws {
+ let container = try decoder.singleValueContainer()
+ let ipString = try container.decode(String.self)
+
+ if let decoded = IPv6Address(ipString) {
+ self = decoded
+ } else {
+ throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid IPv6 representation")
+ }
+ }
+
+ public func encode(to encoder: Encoder) throws {
+ var container = encoder.singleValueContainer()
+
+ try container.encode(String(reflecting: self))
+ }
+}
diff --git a/ios/MullvadVPN/JSONRequestProcedure.swift b/ios/MullvadVPN/JsonRequestProcedure.swift
index 6b6527b6f1..762bb1f1b3 100644
--- a/ios/MullvadVPN/JSONRequestProcedure.swift
+++ b/ios/MullvadVPN/JsonRequestProcedure.swift
@@ -1,5 +1,5 @@
//
-// JSONRequestProcedure.swift
+// JsonRequestProcedure.swift
// MullvadVPN
//
// Created by pronebird on 14/05/2019.
@@ -9,7 +9,7 @@
import Foundation
import ProcedureKit
-final class JSONRequestProcedure<Input, Output: Decodable>: GroupProcedure, InputProcedure, OutputProcedure {
+final class JsonRequestProcedure<Input, Output: Decodable>: GroupProcedure, InputProcedure, OutputProcedure {
typealias URLRequestBuilder = (Input) throws -> URLRequest
@@ -20,6 +20,7 @@ final class JSONRequestProcedure<Input, Output: Decodable>: GroupProcedure, Inpu
self.input = input.flatMap { .ready($0) } ?? .pending
let createRequest = TransformProcedure { try requestBuilder($0) }
+ createRequest.input = self.input
let networkRequest = NetworkProcedure {
NetworkDataProcedure(session: URLSession.shared)
@@ -27,20 +28,18 @@ final class JSONRequestProcedure<Input, Output: Decodable>: GroupProcedure, Inpu
let payloadParsing = DecodeJSONProcedure<Output>(
dateDecodingStrategy: .iso8601,
+ dataDecodingStrategy: .base64,
keyDecodingStrategy: .convertFromSnakeCase
).injectPayload(fromNetwork: networkRequest)
super.init(dispatchQueue: underlyingQueue, operations: [createRequest, networkRequest, payloadParsing])
bind(from: payloadParsing)
-
- addWillExecuteBlockObserver { (procedure, _) in
- createRequest.input = procedure.input
- }
+ bindAndNotifySetInputReady(to: createRequest)
}
}
-extension JSONRequestProcedure where Input == Void {
+extension JsonRequestProcedure where Input == Void {
convenience init(requestBuilder: @escaping URLRequestBuilder) {
self.init(input: (), requestBuilder: requestBuilder)
}
diff --git a/ios/MullvadVPN/JsonRpc.swift b/ios/MullvadVPN/JsonRpc.swift
index ac1d44660c..6c54bf6adb 100644
--- a/ios/MullvadVPN/JsonRpc.swift
+++ b/ios/MullvadVPN/JsonRpc.swift
@@ -8,26 +8,36 @@
import Foundation
-typealias JsonRpcRequestId = String
-struct JsonRpcRequest<T: Encodable>: Encodable {
+extension Encodable {
+ fileprivate func encode(to container: inout SingleValueEncodingContainer) throws {
+ try container.encode(self)
+ }
+}
+
+struct AnyEncodable : Encodable {
+ let value: Encodable
+
+ init(_ value: Encodable) {
+ self.value = value
+ }
+
+ func encode(to encoder: Encoder) throws {
+ var container = encoder.singleValueContainer()
+ try value.encode(to: &container)
+ }
+}
+
+struct JsonRpcRequest: Encodable {
let version = "2.0"
- let id: JsonRpcRequestId = UUID().uuidString
+ let id = UUID().uuidString
let method: String
- let params: [T]
+ let params: [AnyEncodable]
fileprivate enum CodingKeys: String, CodingKey {
case version = "jsonrpc", id, method, params
}
}
-extension JsonRpcRequest where T == NoData {
- init(method: String) {
- self.init(method: method, params: [])
- }
-}
-
-struct NoData: Encodable {}
-
class JsonRpcResponseError: Error, Decodable {
let code: Int
let message: String
@@ -50,7 +60,7 @@ class JsonRpcResponseError: Error, Decodable {
struct JsonRpcResponse<T: Decodable>: Decodable {
let version: String
- let id: JsonRpcRequestId
+ let id: String
let result: Result<T, JsonRpcResponseError>
private enum CodingKeys: String, CodingKey {
diff --git a/ios/MullvadVPN/MullvadAPI.swift b/ios/MullvadVPN/MullvadAPI.swift
index 28bc9f9894..fe2160af68 100644
--- a/ios/MullvadVPN/MullvadAPI.swift
+++ b/ios/MullvadVPN/MullvadAPI.swift
@@ -7,23 +7,30 @@
//
import Foundation
+import Network
import ProcedureKit
private let kMullvadAPIURL = URL(string: "https://api.mullvad.net/rpc/")!
class MullvadAPI {
- class func getRelayList() -> JSONRequestProcedure<Void, JsonRpcResponse<RelayList>> {
- return JSONRequestProcedure(requestBuilder: {
- try makeURLRequest(method: "POST", rpcRequest: JsonRpcRequest(method: "relay_list_v2"))
+ struct WireguardKeyRequest: Codable {
+ var accountToken: String
+ var publicKey: Data
+ }
+
+ class func getRelayList() -> JsonRequestProcedure<Void, JsonRpcResponse<RelayList>> {
+ return JsonRequestProcedure(requestBuilder: {
+ try makeURLRequest(method: "POST",
+ rpcRequest: JsonRpcRequest(method: "relay_list_v2", params: []))
})
}
- class func getAccountExpiry(accountToken: String? = nil) -> JSONRequestProcedure<String, JsonRpcResponse<Date>> {
- return JSONRequestProcedure(input: accountToken, requestBuilder: {
+ class func getAccountExpiry(accountToken: String? = nil) -> JsonRequestProcedure<String, JsonRpcResponse<Date>> {
+ return JsonRequestProcedure(input: accountToken, requestBuilder: {
try makeURLRequest(
method: "POST",
- rpcRequest: JsonRpcRequest(method: "get_expiry", params: [$0])
+ rpcRequest: JsonRpcRequest(method: "get_expiry", params: [AnyEncodable($0)])
)
})
}
@@ -32,10 +39,31 @@ class MullvadAPI {
return AccountVerificationProcedure(accountToken: accountToken)
}
- private class func makeURLRequest<T: Encodable>(method: String, rpcRequest: JsonRpcRequest<T>) throws -> URLRequest {
+ class func pushWireguardKey(_ pushRequest: WireguardKeyRequest? = nil) -> JsonRequestProcedure<WireguardKeyRequest, JsonRpcResponse<WireguardAssociatedAddresses>> {
+ return JsonRequestProcedure(input: pushRequest, requestBuilder: { (input) -> URLRequest in
+ let rpcRequest = JsonRpcRequest(method: "push_wg_key", params: [
+ AnyEncodable(input.accountToken),
+ AnyEncodable(input.publicKey)
+ ])
+ return try makeURLRequest(method: "POST", rpcRequest: rpcRequest)
+ })
+ }
+
+ class func checkWireguardKey(_ pushRequest: WireguardKeyRequest? = nil) -> JsonRequestProcedure<WireguardKeyRequest, JsonRpcResponse<Bool>> {
+ return JsonRequestProcedure(input: pushRequest, requestBuilder: { (input) -> URLRequest in
+ let rpcRequest = JsonRpcRequest(method: "check_wg_key", params: [
+ AnyEncodable(input.accountToken),
+ AnyEncodable(input.publicKey)
+ ])
+ return try makeURLRequest(method: "POST", rpcRequest: rpcRequest)
+ })
+ }
+
+ private class func makeURLRequest(method: String, rpcRequest: JsonRpcRequest) throws -> URLRequest {
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
encoder.dateEncodingStrategy = .iso8601
+ encoder.dataEncodingStrategy = .base64
var urlRequest = URLRequest(url: kMullvadAPIURL)
urlRequest.httpMethod = method
diff --git a/ios/MullvadVPN/ProcedureKit+Patches.swift b/ios/MullvadVPN/ProcedureKit+Patches.swift
new file mode 100644
index 0000000000..86b644f6a2
--- /dev/null
+++ b/ios/MullvadVPN/ProcedureKit+Patches.swift
@@ -0,0 +1,49 @@
+//
+// ProcedureKit+Patches.swift
+// MullvadVPN
+//
+// Created by pronebird on 10/06/2019.
+// Copyright © 2019 Amagicom AB. All rights reserved.
+//
+
+import ProcedureKit
+
+extension InputProcedure {
+
+ /// The original implementation of bind(to: T) has a bug
+ /// This is an attempt to temporarily patch it.
+ /// Github issue: https://github.com/ProcedureKit/ProcedureKit/issues/936
+ func bindAndNotifySetInputReady<T: InputProcedure>(to target: T) where T.Input == Self.Input {
+ addDidSetInputReadyBlockObserver { (procedure) in
+ if case .ready = procedure.input {
+ target.input = procedure.input
+ target.didSetInputReady()
+ }
+ }
+ }
+}
+
+extension ProcedureResult {
+ /// Turn ProcedureResult into Swift 5 Result<T, Error>
+ func into() -> Result<Value, Error> {
+ switch self {
+ case .success(let value):
+ return .success(value)
+ case .failure(let error):
+ return .failure(error)
+ }
+ }
+}
+
+extension Result {
+ /// Turn Swift 5 Result<T, _> into ProcedureResult<T>
+ func into() -> ProcedureResult<Success> {
+ switch self {
+ case .success(let value):
+ return .success(value)
+ case .failure(let error):
+ return .failure(error)
+ }
+ }
+
+}
diff --git a/ios/MullvadVPN/WireguardAssociatedAddresses.swift b/ios/MullvadVPN/WireguardAssociatedAddresses.swift
new file mode 100644
index 0000000000..c4c543d832
--- /dev/null
+++ b/ios/MullvadVPN/WireguardAssociatedAddresses.swift
@@ -0,0 +1,15 @@
+//
+// WireguardAssociatedAddresses.swift
+// MullvadVPN
+//
+// Created by pronebird on 13/06/2019.
+// Copyright © 2019 Amagicom AB. All rights reserved.
+//
+
+import Foundation
+import Network
+
+struct WireguardAssociatedAddresses: Codable {
+ let ipv4Address: IPAddressRange
+ let ipv6Address: IPAddressRange
+}