From fe7317b675a66a9c35c5ff8767dbeec21ce30e28 Mon Sep 17 00:00:00 2001 From: Adam Pritchard Date: Tue, 18 Apr 2017 14:24:00 -0400 Subject: [PATCH 1/3] Remove no-longer-correct comment --- MobileLibrary/iOS/build-psiphon-framework.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 From c131ca8ada299acfbd1c662a35d0d069ae74d4b5 Mon Sep 17 00:00:00 2001 From: Adam Pritchard Date: Wed, 26 Apr 2017 15:49:33 -0400 Subject: [PATCH 2/3] Use multi-URL config params Instead of deprecated single-URL params. Specifically, using these: RemoteServerListURLs, ObfuscatedServerListRootURLs, UpgradeDownloadURLs --- .../PsiphonTunnel/PsiphonTunnel.h | 9 +++--- .../PsiphonTunnel/PsiphonTunnel.m | 31 ++++++++++++++----- .../psiphon-config.json.stub | 4 ++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h index 77cc3ed28..d6489bbc0 100644 --- a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h +++ b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h @@ -53,10 +53,10 @@ 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` 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 +67,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 +83,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/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 */ } From eebb8f37e4c231c3914cf2d14b5492960145e489 Mon Sep 17 00:00:00 2001 From: Adam Pritchard Date: Thu, 27 Apr 2017 12:52:03 -0400 Subject: [PATCH 3/3] Read embedded server entries from a resource file The embedded server entries can be very large, and putting them in source code as a string is unwieldy. It makes much more sense for them to be read from a file (and then we can just provide that file to the library consumer). --- .../PsiphonTunnel/PsiphonTunnel.h | 1 + .../project.pbxproj | 4 +++ .../TunneledWebRequest/ViewController.swift | 25 +++++++++++++++++-- .../psiphon-embedded-server-entries.txt.stub | 2 ++ 4 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 MobileLibrary/iOS/SampleApps/TunneledWebRequest/TunneledWebRequest/psiphon-embedded-server-entries.txt.stub diff --git a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h index d6489bbc0..c5c96ecf1 100644 --- a/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h +++ b/MobileLibrary/iOS/PsiphonTunnel/PsiphonTunnel/PsiphonTunnel.h @@ -57,6 +57,7 @@ FOUNDATION_EXPORT const unsigned char PsiphonTunnelVersionString[]; - `RemoteServerListSignaturePublicKey` - Obfuscated server list functionality is also not strictly required, but aids circumvention ability. - `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. 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-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.)