diff --git a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h index 77cc3ed28..c5c96ecf1 100644 --- a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h +++ b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h @@ -53,10 +53,11 @@ FOUNDATION_EXPORT const unsigned char PsiphonTunnelVersionString[]; - `PropagationChannelId` - `SponsorId` - Remote server list functionality is not strictly required, but absence greatly undermines circumvention ability. - - `RemoteServerListUrl` + - `RemoteServerListURLs` - `RemoteServerListSignaturePublicKey` - Obfuscated server list functionality is also not strictly required, but aids circumvention ability. - - `ObfuscatedServerListRootURL` + - `ObfuscatedServerListRootURLs` + - `RemoteServerListSignaturePublicKey`: This is the same field as above. It is required if either `RemoteServerListURLs` or `ObfuscatedServerListRootURLs` is supplied. Optional fields (if you don't need them, don't set them): - `DataStoreDirectory`: If not set, the library will use a sane location. Override if the client wants to restrict where operational data is kept. If overridden, the directory must already exist and be writable. @@ -67,9 +68,9 @@ FOUNDATION_EXPORT const unsigned char PsiphonTunnelVersionString[]; - `EgressRegion` - `EstablishTunnelTimeoutSeconds` - Should only be set if the Psiphon library is handling upgrade downloading (which it usually is _not_): - - `UpgradeDownloadUrl` + - `UpgradeDownloadURLs` - `UpgradeDownloadClientVersionHeader` - - `UpgradeDownloadFilename` + - `UpgradeDownloadFilename`: Will be set to a sane default if not supplied. - Only set if disabling timeouts (for very slow network connections): - `TunnelConnectTimeoutSeconds` - `TunnelPortForwardDialTimeoutSeconds` @@ -83,7 +84,6 @@ FOUNDATION_EXPORT const unsigned char PsiphonTunnelVersionString[]; - `LocalHttpProxyPort` - `LocalSocksProxyPort` - `TunnelWholeDevice`: For stats purposes, but must be accurate. Defaults to 0 (false). - @endcode @note All other config fields must not be set. diff --git a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m index 2b68b65ab..bee7ffaa5 100644 --- a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m +++ b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.m @@ -234,9 +234,9 @@ -(NSString * _Nullable)getConfig { [self logMessage:[NSString stringWithFormat: @"RemoteServerListDownloadFilename overridden from '%@' to '%@'", defaultRemoteServerListFilename, config[@"RemoteServerListDownloadFilename"]]]; } - // If RemoteServerListUrl and RemoteServerListSignaturePublicKey are absent, - // we'll just leave them out, but we'll log about it. - if (config[@"RemoteServerListUrl"] == nil || + // If RemoteServerListUrl/RemoteServerListURLs and RemoteServerListSignaturePublicKey + // are absent, we'll just leave them out, but we'll log about it. + if ((config[@"RemoteServerListUrl"] == nil && config[@"RemoteServerListURLs"] == nil) || config[@"RemoteServerListSignaturePublicKey"] == nil) { [self logMessage:@"Remote server list functionality will be disabled"]; } @@ -264,11 +264,29 @@ -(NSString * _Nullable)getConfig { [self logMessage:[NSString stringWithFormat: @"ObfuscatedServerListDownloadDirectory overridden from '%@' to '%@'", [defaultOSLDirectoryURL path], config[@"ObfuscatedServerListDownloadDirectory"]]]; } - // If ObfuscatedServerListRootURL is absent, we'll leave it out, but log the absence. - if (config[@"ObfuscatedServerListRootURL"] == nil) { + // If ObfuscatedServerListRootURL/ObfuscatedServerListRootURLs is absent, + // we'll leave it out, but log the absence. + if (config[@"ObfuscatedServerListRootURL"] == nil && config[@"ObfuscatedServerListRootURLs"] == nil) { [self logMessage:@"Obfuscated server list functionality will be disabled"]; } + // + // Upgrade Download Filename + // + + NSString *defaultUpgradeDownloadFilename = [[libraryURL URLByAppendingPathComponent:@"upgrade_download_file" isDirectory:NO] path]; + if (defaultUpgradeDownloadFilename == nil) { + [self logMessage:@"Unable to create defaultUpgradeDownloadFilename"]; + return nil; + } + + if (config[@"UpgradeDownloadFilename"] == nil) { + config[@"UpgradeDownloadFilename"] = defaultUpgradeDownloadFilename; + } + else { + [self logMessage:[NSString stringWithFormat: @"UpgradeDownloadFilename overridden from '%@' to '%@'", defaultUpgradeDownloadFilename, config[@"UpgradeDownloadFilename"]]]; + } + // Other optional fields not being altered. If not set, their defaults will be used: // * EstablishTunnelTimeoutSeconds // * TunnelWholeDevice @@ -277,9 +295,8 @@ -(NSString * _Nullable)getConfig { // * UpstreamProxyUrl // * EmitDiagnosticNotices // * EgressRegion - // * UpgradeDownloadUrl + // * UpgradeDownloadUrl/UpgradeDownloadURLs // * UpgradeDownloadClientVersionHeader - // * UpgradeDownloadFilename // * timeout fields // diff --git a/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest.xcodeproj/project.pbxproj b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest.xcodeproj/project.pbxproj index 865c41ed0..ae6ccde9a 100644 --- a/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest.xcodeproj/project.pbxproj +++ b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 6626590E1DCB8CF400872F6C /* TunneledWebRequestUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6626590D1DCB8CF400872F6C /* TunneledWebRequestUITests.swift */; }; 662659211DCBC7C300872F6C /* PsiphonTunnel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 662659201DCBC7C300872F6C /* PsiphonTunnel.framework */; }; 662659231DCBC8D800872F6C /* PsiphonTunnel.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 662659201DCBC7C300872F6C /* PsiphonTunnel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */; }; 6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 6688DBB51DCD684B00721A9E /* psiphon-config.json */; }; /* End PBXBuildFile section */ @@ -64,6 +65,7 @@ 6626590D1DCB8CF400872F6C /* TunneledWebRequestUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunneledWebRequestUITests.swift; sourceTree = ""; }; 6626590F1DCB8CF400872F6C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 662659201DCBC7C300872F6C /* PsiphonTunnel.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = PsiphonTunnel.framework; sourceTree = ""; }; + 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "psiphon-embedded-server-entries.txt"; sourceTree = ""; }; 6688DBB51DCD684B00721A9E /* psiphon-config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "psiphon-config.json"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -123,6 +125,7 @@ 662658F61DCB8CF300872F6C /* LaunchScreen.storyboard */, 662658F91DCB8CF300872F6C /* Info.plist */, 6688DBB51DCD684B00721A9E /* psiphon-config.json */, + 6682D90D1EB1334000329958 /* psiphon-embedded-server-entries.txt */, 662659201DCBC7C300872F6C /* PsiphonTunnel.framework */, ); path = TunneledWebRequest; @@ -260,6 +263,7 @@ files = ( 662658F81DCB8CF300872F6C /* LaunchScreen.storyboard in Resources */, 662658F51DCB8CF300872F6C /* Assets.xcassets in Resources */, + 6682D90E1EB1334000329958 /* psiphon-embedded-server-entries.txt in Resources */, 662658F31DCB8CF300872F6C /* Main.storyboard in Resources */, 6688DBB61DCD684B00721A9E /* psiphon-config.json in Resources */, ); diff --git a/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/ViewController.swift b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/ViewController.swift index 9bb59aa8b..edb64e949 100644 --- a/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/ViewController.swift +++ b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/ViewController.swift @@ -37,7 +37,12 @@ class ViewController: UIViewController { // Start up the tunnel and begin connecting. // This could be started elsewhere or earlier. NSLog("Starting tunnel") - let embeddedServerEntries = "" + + guard let embeddedServerEntries = getEmbeddedServerEntries() else { + NSLog("getEmbeddedServerEntries failed!") + return + } + guard let success = self.psiphonTunnel?.start(embeddedServerEntries), success else { NSLog("psiphonTunnel.start returned false") return @@ -63,6 +68,22 @@ class ViewController: UIViewController { .replacingOccurrences(of: "\r", with: "") self.webView.stringByEvaluatingJavaScript(from: String.init(format: "document.body.innerHTML+='
%@

'", arguments: [escapedText])) } + + /// Read the Psiphon embedded server entries resource file and return the contents. + /// * returns: The string of the contents of the file. + func getEmbeddedServerEntries() -> String? { + guard let psiphonEmbeddedServerEntriesUrl = Bundle.main.url(forResource: "psiphon-embedded-server-entries", withExtension: "txt") else { + NSLog("Error getting Psiphon embedded server entries resource file URL!") + return nil + } + + do { + return try String.init(contentsOf: psiphonEmbeddedServerEntriesUrl) + } catch { + NSLog("Error reading Psiphon embedded server entries resource file!") + return nil + } + } /// Request URL using URLSession configured to use the current proxy. /// * parameters: @@ -209,7 +230,7 @@ extension ViewController: TunneledAppDelegate { do { return try String.init(contentsOf: psiphonConfigUrl) } catch { - NSLog("Error getting Psiphon config resource file URL!") + NSLog("Error reading Psiphon config resource file!") return nil } } diff --git a/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-config.json.stub b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-config.json.stub index 03d0ba1ba..1059672d4 100644 --- a/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-config.json.stub +++ b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-config.json.stub @@ -9,5 +9,7 @@ All other values will be provided to you by Psiphon Inc. "PropagationChannelId": "...", "SponsorId": "...", "RemoteServerListSignaturePublicKey": "...", - "RemoteServerListUrl": "..." + "RemoteServerListURLs": "[...]", + "ObfuscatedServerListRootURLs": "[...]", + "EmitDiagnosticNotices": true /* Useful when testing */ } diff --git a/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-embedded-server-entries.txt.stub b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-embedded-server-entries.txt.stub new file mode 100644 index 000000000..798e4575e --- /dev/null +++ b/MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-embedded-server-entries.txt.stub @@ -0,0 +1,2 @@ +Embedded server entries supplied by Psiphon Inc. go here. +This file should be empty if embedded server entries are not being used. (But they should be used.) diff --git a/MobileLibrary/iOS/build-psiphon-framework.sh b/MobileLibrary/iOS/build-psiphon-framework.sh index 4a4233362..afa7a0394 100755 --- a/MobileLibrary/iOS/build-psiphon-framework.sh +++ b/MobileLibrary/iOS/build-psiphon-framework.sh @@ -65,7 +65,6 @@ export PATH=${GOPATH}/bin:${PATH} # The GOPATH we're using is temporary, so make sure there isn't one from a previous run. rm -rf ${GOPATH} -# When updating the pinned rev, you will have to manually delete go-ios-build GOMOBILE_PINNED_REV=eb9032959f05f108b05721914dfe09cfa0c5131d GOMOBILE_PATH=${GOPATH}/src/golang.org/x/mobile/cmd/gomobile @@ -144,9 +143,9 @@ git checkout master git checkout -b pinned ${GOMOBILE_PINNED_REV} go install -${GOPATH}/bin/gomobile init -v +${GOPATH}/bin/gomobile init -v -x if [[ $? != 0 ]]; then - echo "FAILURE: ${GOPATH}/bin/gomobile init -v" + echo "FAILURE: ${GOPATH}/bin/gomobile init" exit 1 fi