From 16b1622bea3a88a2927ac8464d3b6fb643e7d11a Mon Sep 17 00:00:00 2001 From: Mikunj Date: Tue, 21 May 2019 15:45:16 +1000 Subject: [PATCH 01/10] Updated imports. --- SignalServiceKit/src/Loki/Crypto/OWSPrimaryStorage+Loki.h | 4 ++-- SignalServiceKit/src/Loki/Crypto/SessionCipher+Loki.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SignalServiceKit/src/Loki/Crypto/OWSPrimaryStorage+Loki.h b/SignalServiceKit/src/Loki/Crypto/OWSPrimaryStorage+Loki.h index 9a9a694b4..647fafc88 100644 --- a/SignalServiceKit/src/Loki/Crypto/OWSPrimaryStorage+Loki.h +++ b/SignalServiceKit/src/Loki/Crypto/OWSPrimaryStorage+Loki.h @@ -1,6 +1,6 @@ #import "OWSPrimaryStorage.h" -#import "PreKeyRecord.h" -#import "PreKeyBundle.h" +#import +#import #import NS_ASSUME_NONNULL_BEGIN diff --git a/SignalServiceKit/src/Loki/Crypto/SessionCipher+Loki.h b/SignalServiceKit/src/Loki/Crypto/SessionCipher+Loki.h index ad261ebf9..b966b96c4 100644 --- a/SignalServiceKit/src/Loki/Crypto/SessionCipher+Loki.h +++ b/SignalServiceKit/src/Loki/Crypto/SessionCipher+Loki.h @@ -1,6 +1,6 @@ // Loki: Refer to Docs/SessionReset.md for explanations -#import "SessionCipher.h" +#import NS_ASSUME_NONNULL_BEGIN From ab1394025242ffca460f07efd1da2f001d846816 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Tue, 21 May 2019 15:56:30 +1000 Subject: [PATCH 02/10] Added GCDWebServer. --- Podfile | 3 +++ Podfile.lock | 8 +++++++- Pods | 2 +- Signal.xcodeproj/project.pbxproj | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Podfile b/Podfile index 90011102c..0c18e171f 100644 --- a/Podfile +++ b/Podfile @@ -69,6 +69,9 @@ target 'Signal' do project 'Signal' shared_pods pod 'SSZipArchive', :inhibit_warnings => true + + # Loki + pod 'GCDWebServer', '~> 3.0' target 'SignalTests' do inherit! :search_paths diff --git a/Podfile.lock b/Podfile.lock index 7ea048b0d..dd272bda9 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -36,6 +36,9 @@ PODS: - Curve25519Kit/Tests (2.1.0): - CocoaLumberjack - SignalCoreKit + - GCDWebServer (3.5.2): + - GCDWebServer/Core (= 3.5.2) + - GCDWebServer/Core (3.5.2) - GRKOpenSSLFramework (1.0.2.12) - HKDFKit (0.0.4): - CocoaLumberjack @@ -194,6 +197,7 @@ DEPENDENCIES: - CryptoSwift - Curve25519Kit (from `https://github.com/signalapp/Curve25519Kit`) - Curve25519Kit/Tests (from `https://github.com/signalapp/Curve25519Kit`) + - GCDWebServer (~> 3.0) - GRKOpenSSLFramework (from `https://github.com/signalapp/GRKOpenSSLFramework`) - HKDFKit (from `https://github.com/signalapp/HKDFKit.git`) - HKDFKit/Tests (from `https://github.com/signalapp/HKDFKit.git`) @@ -218,6 +222,7 @@ SPEC REPOS: - AFNetworking - CocoaLumberjack - CryptoSwift + - GCDWebServer - libPhoneNumber-iOS - PromiseKit - PureLayout @@ -289,6 +294,7 @@ SPEC CHECKSUMS: CocoaLumberjack: 2f44e60eb91c176d471fdba43b9e3eae6a721947 CryptoSwift: d81eeaa59dc5a8d03720fe919a6fd07b51f7439f Curve25519Kit: b3e77b7152ebe95fee2b3fb6c955449492bc14f7 + GCDWebServer: ead88cd14596dd4eae4f5830b8877c87c8728990 GRKOpenSSLFramework: 8a3735ad41e7dc1daff460467bccd32ca5d6ae3e HKDFKit: 3b6dbbb9d59c221cc6c52c3aa915700cbf24e376 libPhoneNumber-iOS: e444379ac18bbfbdefad571da735b2cd7e096caa @@ -307,6 +313,6 @@ SPEC CHECKSUMS: YapDatabase: b418a4baa6906e8028748938f9159807fd039af4 YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54 -PODFILE CHECKSUM: beb49888a2355e89f15280fcfa5105ddc59a5c0a +PODFILE CHECKSUM: 708b5bc644a63e9bc55c409ac292c88c8ee78fad COCOAPODS: 1.5.3 diff --git a/Pods b/Pods index e5b45b28d..d2c312cc2 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit e5b45b28d5e8e409c1acf15c32d3734bb3e8acd7 +Subproject commit d2c312cc2152c929ecfe4fe61ea2e7a3eef90fdf diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index c5a7426fb..ad7131bfb 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -3257,6 +3257,7 @@ "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework", "${BUILT_PRODUCTS_DIR}/Curve25519Kit/Curve25519Kit.framework", + "${BUILT_PRODUCTS_DIR}/GCDWebServer/GCDWebServer.framework", "${PODS_ROOT}/GRKOpenSSLFramework/OpenSSL-iOS/bin/openssl.framework", "${BUILT_PRODUCTS_DIR}/HKDFKit/HKDFKit.framework", "${BUILT_PRODUCTS_DIR}/Mantle/Mantle.framework", @@ -3282,6 +3283,7 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Curve25519Kit.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GCDWebServer.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/HKDFKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mantle.framework", From a32cdfeb1072d2fb6cad6784010362c6d2b724ae Mon Sep 17 00:00:00 2001 From: Mikunj Date: Tue, 21 May 2019 16:20:28 +1000 Subject: [PATCH 03/10] Added LokiP2PServer --- Signal.xcodeproj/project.pbxproj | 4 ++++ Signal/src/Loki/LokiP2PServer.swift | 32 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 Signal/src/Loki/LokiP2PServer.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index ad7131bfb..3a7a05cd9 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 24A830A22293CD0100F4CAC0 /* LokiP2PServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */; }; 2AE2882E4C2B96BFFF9EE27C /* Pods_SignalShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F94C85CB0B235DA37F68ED0 /* Pods_SignalShareExtension.framework */; }; 3403B95D20EA9527001A1F44 /* OWSContactShareButtonsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3403B95B20EA9526001A1F44 /* OWSContactShareButtonsView.m */; }; 34074F61203D0CBE004596AE /* OWSSounds.m in Sources */ = {isa = PBXBuildFile; fileRef = 34074F5F203D0CBD004596AE /* OWSSounds.m */; }; @@ -654,6 +655,7 @@ 0F94C85CB0B235DA37F68ED0 /* Pods_SignalShareExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SignalShareExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1C93CF3971B64E8B6C1F9AC1 /* Pods-SignalShareExtension.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SignalShareExtension.test.xcconfig"; path = "Pods/Target Support Files/Pods-SignalShareExtension/Pods-SignalShareExtension.test.xcconfig"; sourceTree = ""; }; 1CE3CD5C23334683BDD3D78C /* Pods-Signal.test.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Signal.test.xcconfig"; path = "Pods/Target Support Files/Pods-Signal/Pods-Signal.test.xcconfig"; sourceTree = ""; }; + 24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiP2PServer.swift; sourceTree = ""; }; 264242150E87D10A357DB07B /* Pods_SignalMessaging.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SignalMessaging.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3403B95B20EA9526001A1F44 /* OWSContactShareButtonsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactShareButtonsView.m; sourceTree = ""; }; 3403B95C20EA9527001A1F44 /* OWSContactShareButtonsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactShareButtonsView.h; sourceTree = ""; }; @@ -2606,6 +2608,7 @@ B821F2F72272CED3002C88C0 /* OnboardingAccountDetailsViewController.swift */, B821F2F92272CEEE002C88C0 /* OnboardingKeyPairViewController.swift */, B8439519228510FB000563FE /* Poller.swift */, + 24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */, ); path = Loki; sourceTree = ""; @@ -3641,6 +3644,7 @@ 4C4AEC4520EC343B0020E72B /* DismissableTextField.swift in Sources */, 4CB5F26720F6E1E2004D1B42 /* MenuActionsViewController.swift in Sources */, 3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */, + 24A830A22293CD0100F4CAC0 /* LokiP2PServer.swift in Sources */, 349ED990221B0194008045B0 /* Onboarding2FAViewController.swift in Sources */, 45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */, 340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */, diff --git a/Signal/src/Loki/LokiP2PServer.swift b/Signal/src/Loki/LokiP2PServer.swift new file mode 100644 index 000000000..577d368fd --- /dev/null +++ b/Signal/src/Loki/LokiP2PServer.swift @@ -0,0 +1,32 @@ +import GCDWebServer + +@objc class LokiP2PServer : NSObject { + private lazy var webServer: GCDWebServer = { + let webServer = GCDWebServer() + + webServer.addHandler(forMethod: "POST", path: "/v1/storage_rpc", request: GCDWebServerRequest.self) { (request, completionBlock) in + let response = GCDWebServerDataResponse(html: "

Hello World

") + completionBlock(response) + } + + return webServer + }() + + @objc public var serverURL: URL? { + return webServer.serverURL + } + + @objc public var isRunning: Bool { + return webServer.isRunning + } + + @objc @discardableResult func start(onPort port: UInt) -> Bool { + guard !webServer.isRunning else { return false } + webServer.start(withPort: port, bonjourName: nil) + return true + } + + @objc func stop() { + webServer.stop() + } +} From efa303abebeb3037b37772c063ce999a164e435f Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 22 May 2019 09:15:52 +1000 Subject: [PATCH 04/10] Fix mnemonic languages not being linked. --- Podfile.lock | 2 +- Pods | 2 +- SignalServiceKit.podspec | 2 +- SignalServiceKit/src/Loki/Crypto/{Mnemonic => }/Mnemonic.swift | 0 SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/english.txt | 0 SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/japanese.txt | 0 SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/portuguese.txt | 0 SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/spanish.txt | 0 8 files changed, 3 insertions(+), 3 deletions(-) rename SignalServiceKit/src/Loki/Crypto/{Mnemonic => }/Mnemonic.swift (100%) rename SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/english.txt (100%) rename SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/japanese.txt (100%) rename SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/portuguese.txt (100%) rename SignalServiceKit/src/Loki/{Crypto => }/Mnemonic/spanish.txt (100%) diff --git a/Podfile.lock b/Podfile.lock index dd272bda9..08ccc0a45 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -305,7 +305,7 @@ SPEC CHECKSUMS: SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c SignalCoreKit: c2d8132cdedb95d35eb2f8ae7eac0957695d0a8b SignalMetadataKit: 6fa5e9a53c7f104568662521a2f3874672ff7a02 - SignalServiceKit: 54fde76bc75b63bd5e9088acdbd3be0ff7e154d0 + SignalServiceKit: 7f97a29c42328c02ae95f94cce08aa8bc92ab258 SQLCipher: efbdb52cdbe340bcd892b1b14297df4e07241b7f SSZipArchive: 8e859da2520142e09166bc9161967db296e9d02f Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5 diff --git a/Pods b/Pods index d2c312cc2..077f345d2 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit d2c312cc2152c929ecfe4fe61ea2e7a3eef90fdf +Subproject commit 077f345d2993bf2a7dab8df935986e6495e764c7 diff --git a/SignalServiceKit.podspec b/SignalServiceKit.podspec index d70992803..7e4126d02 100644 --- a/SignalServiceKit.podspec +++ b/SignalServiceKit.podspec @@ -36,7 +36,7 @@ An Objective-C library for communicating with the Signal messaging service. s.prefix_header_file = 'SignalServiceKit/src/TSPrefix.h' s.xcconfig = { 'OTHER_CFLAGS' => '$(inherited) -DSQLITE_HAS_CODEC' } - s.resources = ["SignalServiceKit/Resources/Certificates/*"] + s.resources = ["SignalServiceKit/Resources/Certificates/*", "SignalServiceKit/src/Loki/Mnemonic/*.txt"] s.dependency 'Curve25519Kit' s.dependency 'CocoaLumberjack' diff --git a/SignalServiceKit/src/Loki/Crypto/Mnemonic/Mnemonic.swift b/SignalServiceKit/src/Loki/Crypto/Mnemonic.swift similarity index 100% rename from SignalServiceKit/src/Loki/Crypto/Mnemonic/Mnemonic.swift rename to SignalServiceKit/src/Loki/Crypto/Mnemonic.swift diff --git a/SignalServiceKit/src/Loki/Crypto/Mnemonic/english.txt b/SignalServiceKit/src/Loki/Mnemonic/english.txt similarity index 100% rename from SignalServiceKit/src/Loki/Crypto/Mnemonic/english.txt rename to SignalServiceKit/src/Loki/Mnemonic/english.txt diff --git a/SignalServiceKit/src/Loki/Crypto/Mnemonic/japanese.txt b/SignalServiceKit/src/Loki/Mnemonic/japanese.txt similarity index 100% rename from SignalServiceKit/src/Loki/Crypto/Mnemonic/japanese.txt rename to SignalServiceKit/src/Loki/Mnemonic/japanese.txt diff --git a/SignalServiceKit/src/Loki/Crypto/Mnemonic/portuguese.txt b/SignalServiceKit/src/Loki/Mnemonic/portuguese.txt similarity index 100% rename from SignalServiceKit/src/Loki/Crypto/Mnemonic/portuguese.txt rename to SignalServiceKit/src/Loki/Mnemonic/portuguese.txt diff --git a/SignalServiceKit/src/Loki/Crypto/Mnemonic/spanish.txt b/SignalServiceKit/src/Loki/Mnemonic/spanish.txt similarity index 100% rename from SignalServiceKit/src/Loki/Crypto/Mnemonic/spanish.txt rename to SignalServiceKit/src/Loki/Mnemonic/spanish.txt From 748b7eff12bd00a644cf1f9f7ad4e35689a0f786 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 22 May 2019 10:34:08 +1000 Subject: [PATCH 05/10] Start p2p server on app start. Handle more cases in the p2p server. --- Signal/src/AppDelegate.m | 20 ++++++++- Signal/src/Loki/LokiP2PServer.swift | 70 +++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5a708b109..db920b60e 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -66,6 +66,12 @@ static NSTimeInterval launchStartedAt; @end +@interface AppDelegate () + +@property (nonatomic) LokiP2PServer *lokiP2PServer; + +@end + #pragma mark - @implementation AppDelegate @@ -187,6 +193,10 @@ static NSTimeInterval launchStartedAt; OWSLogInfo(@"applicationWillTerminate."); [DDLog flushLog]; + + if (_lokiP2PServer) { + [_lokiP2PServer stop]; + } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { @@ -307,7 +317,15 @@ static NSTimeInterval launchStartedAt; OWSLogInfo(@"application: didFinishLaunchingWithOptions completed."); [OWSAnalytics appLaunchDidBegin]; - + + // Loki + _lokiP2PServer = [LokiP2PServer new]; + if ([_lokiP2PServer startOnPort:8080]) { + OWSLogInfo(@"[Loki P2P Server]: Started server at %@", _lokiP2PServer.serverURL); + } else { + OWSFailDebug(@"Failed to start loki P2P server"); + } + return YES; } diff --git a/Signal/src/Loki/LokiP2PServer.swift b/Signal/src/Loki/LokiP2PServer.swift index 577d368fd..749ef11ff 100644 --- a/Signal/src/Loki/LokiP2PServer.swift +++ b/Signal/src/Loki/LokiP2PServer.swift @@ -1,14 +1,78 @@ import GCDWebServer +// Convenience functions +fileprivate extension GCDWebServerDataRequest { + var truncatedContentType: String? { + guard let contentType = contentType else { return nil } + guard let substring = contentType.split(separator: ";").first else { return contentType } + return String(substring) + } + + // GCDWebServerDataRequest already provides this implementation + // However it will abort when running in DEBUG, we don't want that so we just override it with a version which doesn't abort + var jsonObject: [String: Any]? { + let acceptedMimeTypes = ["application/json", "text/json", "text/javascript"] + guard let mimeType = truncatedContentType, acceptedMimeTypes.contains(mimeType) else { return nil } + + do { + let object = try JSONSerialization.jsonObject(with: data, options: .allowFragments) + return object as? [String: Any] + } catch let error { + Logger.debug("[Loki P2P Server] Failed to serialize json: \(error)") + } + + return nil + } +} + @objc class LokiP2PServer : NSObject { + + private enum StatusCode: Int { + case ok = 200 + case badRequest = 400 + case notFound = 404 + case methodNotAllowed = 405 + case internalServerError = 500 + } + private lazy var webServer: GCDWebServer = { let webServer = GCDWebServer() - webServer.addHandler(forMethod: "POST", path: "/v1/storage_rpc", request: GCDWebServerRequest.self) { (request, completionBlock) in - let response = GCDWebServerDataResponse(html: "

Hello World

") - completionBlock(response) + // Don't allow specific methods + let invalidMethodProcessBlock: (GCDWebServerRequest) -> GCDWebServerResponse? = { _ in + return GCDWebServerResponse(statusCode: StatusCode.methodNotAllowed.rawValue) + } + + let invalidMethods = ["GET", "PUT", "DELETE"] + for method in invalidMethods { + webServer.addDefaultHandler(forMethod: method, request: GCDWebServerRequest.self, processBlock: invalidMethodProcessBlock) } + // By default send 404 for any path + webServer.addDefaultHandler(forMethod: "POST", request: GCDWebServerRequest.self, processBlock: { _ in + return GCDWebServerResponse(statusCode: StatusCode.notFound.rawValue) + }) + + // Handle our specific storage path + webServer.addHandler(forMethod: "POST", path: "/v1/storage_rpc", request: GCDWebServerDataRequest.self, asyncProcessBlock: { (request, completionBlock) in + // Make sure we were sent a good request + guard let dataRequest = request as? GCDWebServerDataRequest, let json = dataRequest.jsonObject else { + completionBlock(GCDWebServerResponse(statusCode: StatusCode.badRequest.rawValue)) + return + } + + // Only allow the store method + guard let method = json["method"] as? String, method == "store" else { + completionBlock(GCDWebServerResponse(statusCode: StatusCode.notFound.rawValue)) + return + } + + // TODO: Decrypt message here + + let response = GCDWebServerResponse(statusCode: StatusCode.ok.rawValue) + completionBlock(response) + }) + return webServer }() From 865bb1932fd9666ba19e703a6069453860bd89a4 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 22 May 2019 11:20:05 +1000 Subject: [PATCH 06/10] Added LokiP2PMessageHandler. Moved wrapping and unwrapping of proto envelopes to LokiMessageWrapper. --- Pods | 2 +- Signal/src/Loki/LokiP2PServer.swift | 33 +++++++++++------ SignalServiceKit/protobuf/SignalService.proto | 4 ++ .../src/Loki/API/LokiAPI+Message.swift | 2 +- SignalServiceKit/src/Loki/API/LokiAPI.swift | 2 +- ...rapping.swift => LokiMessageWrapper.swift} | 9 +++-- .../src/Loki/API/LokiP2PMessageHandler.swift | 37 +++++++++++++++++++ .../src/Protos/Generated/SSKProto.swift | 14 +++++++ .../Protos/Generated/SignalService.pb.swift | 19 ++++++++++ 9 files changed, 104 insertions(+), 18 deletions(-) rename SignalServiceKit/src/Loki/API/{LokiAPI+Wrapping.swift => LokiMessageWrapper.swift} (94%) create mode 100644 SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift diff --git a/Pods b/Pods index 077f345d2..32ca94b0b 160000 --- a/Pods +++ b/Pods @@ -1 +1 @@ -Subproject commit 077f345d2993bf2a7dab8df935986e6495e764c7 +Subproject commit 32ca94b0b45a1f55059ee500c5e217a0f55a0313 diff --git a/Signal/src/Loki/LokiP2PServer.swift b/Signal/src/Loki/LokiP2PServer.swift index 749ef11ff..ab85ca226 100644 --- a/Signal/src/Loki/LokiP2PServer.swift +++ b/Signal/src/Loki/LokiP2PServer.swift @@ -1,6 +1,13 @@ import GCDWebServer // Convenience functions + +fileprivate extension GCDWebServerResponse { + convenience init(statusCode: E) where E.RawValue == Int { + self.init(statusCode: statusCode.rawValue) + } +} + fileprivate extension GCDWebServerDataRequest { var truncatedContentType: String? { guard let contentType = contentType else { return nil } @@ -27,7 +34,7 @@ fileprivate extension GCDWebServerDataRequest { @objc class LokiP2PServer : NSObject { - private enum StatusCode: Int { + fileprivate enum StatusCode: Int { case ok = 200 case badRequest = 400 case notFound = 404 @@ -40,7 +47,7 @@ fileprivate extension GCDWebServerDataRequest { // Don't allow specific methods let invalidMethodProcessBlock: (GCDWebServerRequest) -> GCDWebServerResponse? = { _ in - return GCDWebServerResponse(statusCode: StatusCode.methodNotAllowed.rawValue) + return GCDWebServerResponse(statusCode: StatusCode.methodNotAllowed) } let invalidMethods = ["GET", "PUT", "DELETE"] @@ -50,27 +57,31 @@ fileprivate extension GCDWebServerDataRequest { // By default send 404 for any path webServer.addDefaultHandler(forMethod: "POST", request: GCDWebServerRequest.self, processBlock: { _ in - return GCDWebServerResponse(statusCode: StatusCode.notFound.rawValue) + return GCDWebServerResponse(statusCode: StatusCode.notFound) }) // Handle our specific storage path - webServer.addHandler(forMethod: "POST", path: "/v1/storage_rpc", request: GCDWebServerDataRequest.self, asyncProcessBlock: { (request, completionBlock) in + webServer.addHandler(forMethod: "POST", path: "/v1/storage_rpc", request: GCDWebServerDataRequest.self, processBlock: { request in // Make sure we were sent a good request guard let dataRequest = request as? GCDWebServerDataRequest, let json = dataRequest.jsonObject else { - completionBlock(GCDWebServerResponse(statusCode: StatusCode.badRequest.rawValue)) - return + return GCDWebServerResponse(statusCode: StatusCode.badRequest) } // Only allow the store method guard let method = json["method"] as? String, method == "store" else { - completionBlock(GCDWebServerResponse(statusCode: StatusCode.notFound.rawValue)) - return + return GCDWebServerResponse(statusCode: StatusCode.notFound) + } + + // Make sure we have the data + guard let params = json["params"] as? [String: String], let data = params["data"] else { + return GCDWebServerResponse(statusCode: StatusCode.badRequest) } - // TODO: Decrypt message here + // Pass it off to the message handler + LokiP2PMessageHandler.shared.handleReceivedMessage(base64EncodedData: data) - let response = GCDWebServerResponse(statusCode: StatusCode.ok.rawValue) - completionBlock(response) + // Send a response back + return GCDWebServerResponse(statusCode: StatusCode.ok.rawValue) }) return webServer diff --git a/SignalServiceKit/protobuf/SignalService.proto b/SignalServiceKit/protobuf/SignalService.proto index bc17df0dc..ce2e45d2e 100644 --- a/SignalServiceKit/protobuf/SignalService.proto +++ b/SignalServiceKit/protobuf/SignalService.proto @@ -38,6 +38,10 @@ message Envelope { optional string serverGuid = 9; // We may eventually want to make this required. optional uint64 serverTimestamp = 10; + + // Loki: This field is only here as a helper + // It shouldn't be set when sending a message + optional bool isPtpMessage = 999; } message TypingMessage { diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift index 1c3aa29d9..9d146e264 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift @@ -32,7 +32,7 @@ public extension LokiAPI { return Promise { seal in DispatchQueue.global(qos: .default).async { do { - let wrappedMessage = try wrap(message: signalMessage, timestamp: timestamp) + let wrappedMessage = try LokiMessageWrapper.wrap(message: signalMessage, timestamp: timestamp) let data = wrappedMessage.base64EncodedString() let destination = signalMessage["destination"] as! String let ttl = LokiAPI.defaultMessageTTL diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index 748fcf45d..2fc3cecb3 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -57,7 +57,7 @@ import PromiseKit Logger.warn("[Loki] Failed to decode data for message: \(message).") return nil } - guard let envelope = try? unwrap(data: data) else { + guard let envelope = try? LokiMessageWrapper.unwrap(data: data) else { Logger.warn("[Loki] Failed to unwrap data for message: \(message).") return nil } diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+Wrapping.swift b/SignalServiceKit/src/Loki/API/LokiMessageWrapper.swift similarity index 94% rename from SignalServiceKit/src/Loki/API/LokiAPI+Wrapping.swift rename to SignalServiceKit/src/Loki/API/LokiMessageWrapper.swift index 2a47b47e2..c8fa1e8a8 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+Wrapping.swift +++ b/SignalServiceKit/src/Loki/API/LokiMessageWrapper.swift @@ -1,7 +1,8 @@ -extension LokiAPI { +public class LokiMessageWrapper { + private init() {} - enum WrappingError : LocalizedError { + public enum WrappingError : LocalizedError { case failedToWrapData case failedToWrapMessageInEnvelope case failedToWrapEnvelopeInWebSocketMessage @@ -25,7 +26,7 @@ extension LokiAPI { /// - timestamp: The original message timestamp (`TSOutgoingMessage.timestamp`). /// - Returns: The wrapped message data. /// - Throws: A `WrappingError` if something went wrong. - static func wrap(message: SignalMessage, timestamp: UInt64) throws -> Data { + public static func wrap(message: SignalMessage, timestamp: UInt64) throws -> Data { do { let envelope = try createEnvelope(around: message, timestamp: timestamp) let webSocketMessage = try createWebSocketMessage(around: envelope) @@ -40,7 +41,7 @@ extension LokiAPI { /// - Parameter data: The data from the storage server (not base 64 encoded). /// - Returns: An `SSKProtoEnvelope` object. /// - Throws: A `WrappingError` if something went wrong. - static func unwrap(data: Data) throws -> SSKProtoEnvelope { + public static func unwrap(data: Data) throws -> SSKProtoEnvelope { do { let webSocketMessage = try WebSocketProtoWebSocketMessage.parseData(data) let envelope = webSocketMessage.request!.body! diff --git a/SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift b/SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift new file mode 100644 index 000000000..788edb2f4 --- /dev/null +++ b/SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift @@ -0,0 +1,37 @@ + +public class LokiP2PMessageHandler { + public static let shared = LokiP2PMessageHandler() + + private var messageReceiver: OWSMessageReceiver { + return SSKEnvironment.shared.messageReceiver + } + + private init() {} + + public func handleReceivedMessage(base64EncodedData: String) { + guard let data = Data(base64Encoded: base64EncodedData) else { + Logger.warn("[LokiP2PMessageHandler] Failed to decode p2p message data") + return + } + + guard let envelope = try? LokiMessageWrapper.unwrap(data: data) else { + Logger.warn("[LokiP2PMessageHandler] Failed to unwrap p2p data") + return + } + + // We need to set the p2p field on the envelope + let builder = envelope.asBuilder() + builder.setIsPtpMessage(true) + + // Send it to message receiver + do { + let newEnvelope = try builder.build() + let envelopeData = try newEnvelope.serializedData() + messageReceiver.handleReceivedEnvelopeData(envelopeData) + } catch let error { + Logger.warn("[LokiP2PMessageHandler] Something went wrong while converting proto: \(error)") + owsFailDebug("Failed to build envelope") + } + } + +} diff --git a/SignalServiceKit/src/Protos/Generated/SSKProto.swift b/SignalServiceKit/src/Protos/Generated/SSKProto.swift index e01692b52..5fa154cd9 100644 --- a/SignalServiceKit/src/Protos/Generated/SSKProto.swift +++ b/SignalServiceKit/src/Protos/Generated/SSKProto.swift @@ -80,6 +80,9 @@ public enum SSKProtoError: Error { if hasServerTimestamp { builder.setServerTimestamp(serverTimestamp) } + if hasIsPtpMessage { + builder.setIsPtpMessage(isPtpMessage) + } return builder } @@ -132,6 +135,10 @@ public enum SSKProtoError: Error { proto.serverTimestamp = valueParam } + @objc public func setIsPtpMessage(_ valueParam: Bool) { + proto.isPtpMessage = valueParam + } + @objc public func build() throws -> SSKProtoEnvelope { return try SSKProtoEnvelope.parseProto(proto) } @@ -211,6 +218,13 @@ public enum SSKProtoError: Error { return proto.hasServerTimestamp } + @objc public var isPtpMessage: Bool { + return proto.isPtpMessage + } + @objc public var hasIsPtpMessage: Bool { + return proto.hasIsPtpMessage + } + private init(proto: SignalServiceProtos_Envelope, type: SSKProtoEnvelopeType, timestamp: UInt64) { diff --git a/SignalServiceKit/src/Protos/Generated/SignalService.pb.swift b/SignalServiceKit/src/Protos/Generated/SignalService.pb.swift index faa449417..b5e1f4b26 100644 --- a/SignalServiceKit/src/Protos/Generated/SignalService.pb.swift +++ b/SignalServiceKit/src/Protos/Generated/SignalService.pb.swift @@ -119,6 +119,17 @@ struct SignalServiceProtos_Envelope { /// Clears the value of `serverTimestamp`. Subsequent reads from it will return its default value. mutating func clearServerTimestamp() {self._serverTimestamp = nil} + /// Loki: This field is only here as a helper + /// It shouldn't be set when sending a message + var isPtpMessage: Bool { + get {return _isPtpMessage ?? false} + set {_isPtpMessage = newValue} + } + /// Returns true if `isPtpMessage` has been explicitly set. + var hasIsPtpMessage: Bool {return self._isPtpMessage != nil} + /// Clears the value of `isPtpMessage`. Subsequent reads from it will return its default value. + mutating func clearIsPtpMessage() {self._isPtpMessage = nil} + var unknownFields = SwiftProtobuf.UnknownStorage() enum TypeEnum: SwiftProtobuf.Enum { @@ -175,6 +186,7 @@ struct SignalServiceProtos_Envelope { fileprivate var _content: Data? = nil fileprivate var _serverGuid: String? = nil fileprivate var _serverTimestamp: UInt64? = nil + fileprivate var _isPtpMessage: Bool? = nil } #if swift(>=4.2) @@ -437,6 +449,7 @@ struct SignalServiceProtos_LokiAddressMessage { // methods supported on all messages. /// The naming is a bit different from desktop because of swift auto generation + /// It doesn't like p2p much :( var ptpAddress: String { get {return _ptpAddress ?? String()} set {_ptpAddress = newValue} @@ -2473,6 +2486,7 @@ extension SignalServiceProtos_Envelope: SwiftProtobuf.Message, SwiftProtobuf._Me 8: .same(proto: "content"), 9: .same(proto: "serverGuid"), 10: .same(proto: "serverTimestamp"), + 999: .same(proto: "isPtpMessage"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -2487,6 +2501,7 @@ extension SignalServiceProtos_Envelope: SwiftProtobuf.Message, SwiftProtobuf._Me case 8: try decoder.decodeSingularBytesField(value: &self._content) case 9: try decoder.decodeSingularStringField(value: &self._serverGuid) case 10: try decoder.decodeSingularUInt64Field(value: &self._serverTimestamp) + case 999: try decoder.decodeSingularBoolField(value: &self._isPtpMessage) default: break } } @@ -2520,6 +2535,9 @@ extension SignalServiceProtos_Envelope: SwiftProtobuf.Message, SwiftProtobuf._Me if let v = self._serverTimestamp { try visitor.visitSingularUInt64Field(value: v, fieldNumber: 10) } + if let v = self._isPtpMessage { + try visitor.visitSingularBoolField(value: v, fieldNumber: 999) + } try unknownFields.traverse(visitor: &visitor) } @@ -2533,6 +2551,7 @@ extension SignalServiceProtos_Envelope: SwiftProtobuf.Message, SwiftProtobuf._Me if lhs._content != rhs._content {return false} if lhs._serverGuid != rhs._serverGuid {return false} if lhs._serverTimestamp != rhs._serverTimestamp {return false} + if lhs._isPtpMessage != rhs._isPtpMessage {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } From 2ae665f68290bef756ca2dca5010a7e4383372fb Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 22 May 2019 11:52:32 +1000 Subject: [PATCH 07/10] Bind to a random port if the default one is taken. --- Signal/src/AppDelegate.m | 19 ++++++++++++++----- Signal/src/Loki/LokiP2PServer.swift | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index db920b60e..123349b84 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -320,12 +320,21 @@ static NSTimeInterval launchStartedAt; // Loki _lokiP2PServer = [LokiP2PServer new]; - if ([_lokiP2PServer startOnPort:8080]) { - OWSLogInfo(@"[Loki P2P Server]: Started server at %@", _lokiP2PServer.serverURL); - } else { - OWSFailDebug(@"Failed to start loki P2P server"); + + // We try to bind to 8081, if we can't then we just fallback to any random port + NSArray *ports = @[@8081, @0]; + for (NSNumber *port in ports) { + if (_lokiP2PServer.isRunning) { break; } + if ([_lokiP2PServer startOnPort:port.unsignedIntegerValue]) { + OWSLogInfo(@"[Loki P2P Server]: Started server at %@", _lokiP2PServer.serverURL); + break; + } + } + + if (!_lokiP2PServer.isRunning) { + OWSLogWarn(@"[Loki P2P Server]: Failed to start loki P2P server"); } - + return YES; } diff --git a/Signal/src/Loki/LokiP2PServer.swift b/Signal/src/Loki/LokiP2PServer.swift index ab85ca226..aae5e7bb1 100644 --- a/Signal/src/Loki/LokiP2PServer.swift +++ b/Signal/src/Loki/LokiP2PServer.swift @@ -98,7 +98,7 @@ fileprivate extension GCDWebServerDataRequest { @objc @discardableResult func start(onPort port: UInt) -> Bool { guard !webServer.isRunning else { return false } webServer.start(withPort: port, bonjourName: nil) - return true + return webServer.isRunning } @objc func stop() { From b5cc66262d4e7077b066b9a88d103456bd904e4a Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 22 May 2019 13:00:32 +1000 Subject: [PATCH 08/10] Added ttl property on TSOutgoingMessage. Use this ttl value when sending a message. --- SignalServiceKit/src/Loki/API/LokiAPI+Message.swift | 7 ++++++- SignalServiceKit/src/Loki/API/SignalMessage.swift | 1 + .../src/Loki/Messages/LKFriendRequestMessage.m | 8 +++++++- .../src/Messages/Interactions/TSOutgoingMessage.h | 3 +++ .../src/Messages/Interactions/TSOutgoingMessage.m | 6 ++++++ SignalServiceKit/src/Messages/OWSMessageSender.m | 3 +++ SignalServiceKit/src/Messages/OWSMessageServiceParams.h | 1 + SignalServiceKit/src/Messages/OWSMessageServiceParams.m | 1 + 8 files changed, 28 insertions(+), 2 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift index 9d146e264..95f12f771 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift @@ -35,7 +35,12 @@ public extension LokiAPI { let wrappedMessage = try LokiMessageWrapper.wrap(message: signalMessage, timestamp: timestamp) let data = wrappedMessage.base64EncodedString() let destination = signalMessage["destination"] as! String - let ttl = LokiAPI.defaultMessageTTL + + var ttl = LokiAPI.defaultMessageTTL + if let messageTTL = signalMessage["ttl"] as? UInt, messageTTL > 0 { + ttl = UInt64(messageTTL) + } + if isPoWRequired { // The storage server takes a time interval in milliseconds let now = NSDate.ows_millisecondTimeStamp() diff --git a/SignalServiceKit/src/Loki/API/SignalMessage.swift b/SignalServiceKit/src/Loki/API/SignalMessage.swift index 11d7eec95..f543fe1df 100644 --- a/SignalServiceKit/src/Loki/API/SignalMessage.swift +++ b/SignalServiceKit/src/Loki/API/SignalMessage.swift @@ -1,2 +1,3 @@ +// This is basically OWSMessageServiceParams public typealias SignalMessage = [String:Any] diff --git a/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m b/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m index eed1204c2..3375379f4 100644 --- a/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m +++ b/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m @@ -1,11 +1,17 @@ #import "LKFriendRequestMessage.h" #import "OWSPrimaryStorage+Loki.h" +#import "NSDate+OWS.h" #import "SignalRecipient.h" #import @implementation LKFriendRequestMessage --(BOOL)isFriendRequest { return YES; } +- (BOOL)isFriendRequest { return YES; } + +- (uint)ttl { + // Friend requests should stay for the longest on the storage server + return 4 * kDayInterval; +} - (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient { SSKProtoContentBuilder *contentBuilder = [super contentBuilder:recipient]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h index 93adadaba..25ca6539b 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h @@ -144,6 +144,9 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { // Loki: Bool to indicate if proof of work is being calculated for this message @property (atomic, readonly) BOOL isCalculatingPoW; +// Loki: Time to live for the message +@property (nonatomic, readonly) uint ttl; + /** * The data representation of this message, to be encrypted, before being sent. */ diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index eed46d2b5..197c62fcf 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -1154,6 +1154,12 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt return [result copy]; } +- (uint)ttl { + // Time to live for all messages should be 1 day + // TODO: Change this to return a value that the user chose + return 1 * kDayInterval; +} + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 736a89798..c685f66fb 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1885,6 +1885,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; isSilent:isSilent isOnline:isOnline registrationId:[cipher throws_remoteRegistrationId:transaction]]; + + // Loki: Add the ttl to the message params + messageParams.ttl = message.ttl; NSError *error; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; diff --git a/SignalServiceKit/src/Messages/OWSMessageServiceParams.h b/SignalServiceKit/src/Messages/OWSMessageServiceParams.h index a2e1d9d3f..55a335069 100644 --- a/SignalServiceKit/src/Messages/OWSMessageServiceParams.h +++ b/SignalServiceKit/src/Messages/OWSMessageServiceParams.h @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) NSString *content; @property (nonatomic, readonly) BOOL silent; @property (nonatomic, readonly) BOOL online; +@property (nonatomic) uint ttl; - (instancetype)initWithType:(TSWhisperMessageType)type recipientId:(NSString *)destination diff --git a/SignalServiceKit/src/Messages/OWSMessageServiceParams.m b/SignalServiceKit/src/Messages/OWSMessageServiceParams.m index a2a66121c..16eeb684e 100644 --- a/SignalServiceKit/src/Messages/OWSMessageServiceParams.m +++ b/SignalServiceKit/src/Messages/OWSMessageServiceParams.m @@ -36,6 +36,7 @@ NS_ASSUME_NONNULL_BEGIN _content = [content base64EncodedString]; _silent = isSilent; _online = isOnline; + _ttl = 0; return self; } From 8c8f6231a5c2d4b9acd2f7340ef2d82a8c076ee0 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 22 May 2019 13:24:13 +1000 Subject: [PATCH 09/10] Fix ttl not being set in friend requests. --- SignalServiceKit/src/Loki/API/LokiAPI+Message.swift | 2 +- .../src/Messages/Interactions/TSOutgoingMessage.h | 2 +- SignalServiceKit/src/Messages/OWSMessageSender.m | 12 ++++++------ .../src/Messages/OWSMessageServiceParams.h | 7 +++++-- .../src/Messages/OWSMessageServiceParams.m | 3 ++- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift index 95f12f771..3abc5bd73 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift @@ -7,7 +7,7 @@ public extension LokiAPI { let destination: String /// The content of the message. let data: LosslessStringConvertible - /// The time to live for the message. + /// The time to live for the message in seconds. let ttl: UInt64 /// When the proof of work was calculated, if applicable. /// diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h index 25ca6539b..598b30fa2 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h @@ -144,7 +144,7 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { // Loki: Bool to indicate if proof of work is being calculated for this message @property (atomic, readonly) BOOL isCalculatingPoW; -// Loki: Time to live for the message +// Loki: Time to live for the message in seconds @property (nonatomic, readonly) uint ttl; /** diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index c685f66fb..a89d90664 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1773,6 +1773,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; SignalRecipient *recipient = messageSend.recipient; NSString *recipientId = recipient.recipientId; + TSOutgoingMessage *message = messageSend.message; FallBackSessionCipher *cipher = [[FallBackSessionCipher alloc] initWithRecipientId:recipientId identityKeyStore:self.identityManager]; @@ -1790,7 +1791,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; content:serializedMessage isSilent:false isOnline:false - registrationId:0]; + registrationId:0 + ttl:message.ttl]; NSError *error; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; @@ -1884,14 +1886,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; content:serializedMessage isSilent:isSilent isOnline:isOnline - registrationId:[cipher throws_remoteRegistrationId:transaction]]; - - // Loki: Add the ttl to the message params - messageParams.ttl = message.ttl; + registrationId:[cipher throws_remoteRegistrationId:transaction] + ttl:message.ttl]; NSError *error; NSDictionary *jsonDict = [MTLJSONAdapter JSONDictionaryFromModel:messageParams error:&error]; - + if (error) { OWSProdError([OWSAnalyticsEvents messageSendErrorCouldNotSerializeMessageJson]); return nil; diff --git a/SignalServiceKit/src/Messages/OWSMessageServiceParams.h b/SignalServiceKit/src/Messages/OWSMessageServiceParams.h index 55a335069..3a8dc25c9 100644 --- a/SignalServiceKit/src/Messages/OWSMessageServiceParams.h +++ b/SignalServiceKit/src/Messages/OWSMessageServiceParams.h @@ -23,7 +23,9 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) NSString *content; @property (nonatomic, readonly) BOOL silent; @property (nonatomic, readonly) BOOL online; -@property (nonatomic) uint ttl; + +// Loki: Message ttl +@property (nonatomic, readonly) uint ttl; - (instancetype)initWithType:(TSWhisperMessageType)type recipientId:(NSString *)destination @@ -31,7 +33,8 @@ NS_ASSUME_NONNULL_BEGIN content:(NSData *)content isSilent:(BOOL)isSilent isOnline:(BOOL)isOnline - registrationId:(int)registrationId; + registrationId:(int)registrationId + ttl:(uint)ttl; @end diff --git a/SignalServiceKit/src/Messages/OWSMessageServiceParams.m b/SignalServiceKit/src/Messages/OWSMessageServiceParams.m index 16eeb684e..cfd88bd3e 100644 --- a/SignalServiceKit/src/Messages/OWSMessageServiceParams.m +++ b/SignalServiceKit/src/Messages/OWSMessageServiceParams.m @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN isSilent:(BOOL)isSilent isOnline:(BOOL)isOnline registrationId:(int)registrationId + ttl:(uint)ttl { self = [super init]; @@ -36,7 +37,7 @@ NS_ASSUME_NONNULL_BEGIN _content = [content base64EncodedString]; _silent = isSilent; _online = isOnline; - _ttl = 0; + _ttl = ttl; return self; } From 20472c8bedfc9a19a37ff6434760c0e8ac5e5240 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 22 May 2019 14:29:59 +1000 Subject: [PATCH 10/10] Fix minor code style issues --- Signal/Signal-Info.plist | 2 +- Signal/src/AppDelegate.m | 26 ++++++-------- Signal/src/Loki/LokiP2PServer.swift | 35 ++++++++----------- .../src/Loki/API/LokiAPI+Message.swift | 6 +--- .../src/Loki/API/LokiMessageWrapper.swift | 5 ++- .../src/Loki/API/LokiP2PMessageHandler.swift | 26 ++++++-------- .../Loki/Messages/LKFriendRequestMessage.m | 5 +-- .../SSKProtoPrekeyBundleMessage+Loki.swift | 2 +- .../Messages/Interactions/TSOutgoingMessage.h | 4 +-- .../Messages/Interactions/TSOutgoingMessage.m | 2 +- 10 files changed, 44 insertions(+), 69 deletions(-) diff --git a/Signal/Signal-Info.plist b/Signal/Signal-Info.plist index 7396df8e5..258a90a89 100644 --- a/Signal/Signal-Info.plist +++ b/Signal/Signal-Info.plist @@ -7,7 +7,7 @@ CarthageVersion 0.33.0 OSXVersion - 10.14.4 + 10.14.5 WebRTCCommit 1445d719bf05280270e9f77576f80f973fd847f8 M73 diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 123349b84..676b28697 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -63,12 +63,7 @@ static NSTimeInterval launchStartedAt; @property (nonatomic) BOOL hasInitialRootViewController; @property (nonatomic) BOOL areVersionMigrationsComplete; @property (nonatomic) BOOL didAppLaunchFail; - -@end - -@interface AppDelegate () - -@property (nonatomic) LokiP2PServer *lokiP2PServer; +@property (nonatomic) LKP2PServer *lokiP2PServer; // Loki @end @@ -194,9 +189,7 @@ static NSTimeInterval launchStartedAt; [DDLog flushLog]; - if (_lokiP2PServer) { - [_lokiP2PServer stop]; - } + if (self.lokiP2PServer) { [self.lokiP2PServer stop]; } } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { @@ -319,20 +312,21 @@ static NSTimeInterval launchStartedAt; [OWSAnalytics appLaunchDidBegin]; // Loki - _lokiP2PServer = [LokiP2PServer new]; + self.lokiP2PServer = [LKP2PServer new]; // We try to bind to 8081, if we can't then we just fallback to any random port - NSArray *ports = @[@8081, @0]; + NSArray *ports = @[ @8081, @0 ]; for (NSNumber *port in ports) { - if (_lokiP2PServer.isRunning) { break; } - if ([_lokiP2PServer startOnPort:port.unsignedIntegerValue]) { - OWSLogInfo(@"[Loki P2P Server]: Started server at %@", _lokiP2PServer.serverURL); + if (self.lokiP2PServer.isRunning) { break; } + BOOL isStarted = [self.lokiP2PServer startOnPort:port.unsignedIntegerValue]; + if (isStarted) { + OWSLogInfo(@"[Loki] Started server at %@.", self.lokiP2PServer.serverURL); break; } } - if (!_lokiP2PServer.isRunning) { - OWSLogWarn(@"[Loki P2P Server]: Failed to start loki P2P server"); + if (!self.lokiP2PServer.isRunning) { + OWSLogWarn(@"[Loki] Failed to start P2P server."); } return YES; diff --git a/Signal/src/Loki/LokiP2PServer.swift b/Signal/src/Loki/LokiP2PServer.swift index aae5e7bb1..759b28079 100644 --- a/Signal/src/Loki/LokiP2PServer.swift +++ b/Signal/src/Loki/LokiP2PServer.swift @@ -1,14 +1,13 @@ import GCDWebServer -// Convenience functions - -fileprivate extension GCDWebServerResponse { +private extension GCDWebServerResponse { + convenience init(statusCode: E) where E.RawValue == Int { self.init(statusCode: statusCode.rawValue) } } -fileprivate extension GCDWebServerDataRequest { +private extension GCDWebServerDataRequest { var truncatedContentType: String? { guard let contentType = contentType else { return nil } guard let substring = contentType.split(separator: ";").first else { return contentType } @@ -17,24 +16,25 @@ fileprivate extension GCDWebServerDataRequest { // GCDWebServerDataRequest already provides this implementation // However it will abort when running in DEBUG, we don't want that so we just override it with a version which doesn't abort - var jsonObject: [String: Any]? { - let acceptedMimeTypes = ["application/json", "text/json", "text/javascript"] + var jsonObject: JSON? { + let acceptedMimeTypes = [ "application/json", "text/json", "text/javascript" ] guard let mimeType = truncatedContentType, acceptedMimeTypes.contains(mimeType) else { return nil } do { let object = try JSONSerialization.jsonObject(with: data, options: .allowFragments) - return object as? [String: Any] + return object as? JSON } catch let error { - Logger.debug("[Loki P2P Server] Failed to serialize json: \(error)") + Logger.debug("[Loki] Failed to serialize JSON: \(error).") } return nil } } -@objc class LokiP2PServer : NSObject { +@objc(LKP2PServer) +final class LokiP2PServer : NSObject { - fileprivate enum StatusCode: Int { + private enum StatusCode : Int { case ok = 200 case badRequest = 400 case notFound = 404 @@ -50,7 +50,7 @@ fileprivate extension GCDWebServerDataRequest { return GCDWebServerResponse(statusCode: StatusCode.methodNotAllowed) } - let invalidMethods = ["GET", "PUT", "DELETE"] + let invalidMethods = [ "GET", "PUT", "DELETE" ] for method in invalidMethods { webServer.addDefaultHandler(forMethod: method, request: GCDWebServerRequest.self, processBlock: invalidMethodProcessBlock) } @@ -87,13 +87,8 @@ fileprivate extension GCDWebServerDataRequest { return webServer }() - @objc public var serverURL: URL? { - return webServer.serverURL - } - - @objc public var isRunning: Bool { - return webServer.isRunning - } + @objc public var serverURL: URL? { return webServer.serverURL } + @objc public var isRunning: Bool { return webServer.isRunning } @objc @discardableResult func start(onPort port: UInt) -> Bool { guard !webServer.isRunning else { return false } @@ -101,7 +96,5 @@ fileprivate extension GCDWebServerDataRequest { return webServer.isRunning } - @objc func stop() { - webServer.stop() - } + @objc func stop() { webServer.stop() } } diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift index 3abc5bd73..021348535 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+Message.swift @@ -35,12 +35,8 @@ public extension LokiAPI { let wrappedMessage = try LokiMessageWrapper.wrap(message: signalMessage, timestamp: timestamp) let data = wrappedMessage.base64EncodedString() let destination = signalMessage["destination"] as! String - var ttl = LokiAPI.defaultMessageTTL - if let messageTTL = signalMessage["ttl"] as? UInt, messageTTL > 0 { - ttl = UInt64(messageTTL) - } - + if let messageTTL = signalMessage["ttl"] as? UInt, messageTTL > 0 { ttl = UInt64(messageTTL) } if isPoWRequired { // The storage server takes a time interval in milliseconds let now = NSDate.ows_millisecondTimeStamp() diff --git a/SignalServiceKit/src/Loki/API/LokiMessageWrapper.swift b/SignalServiceKit/src/Loki/API/LokiMessageWrapper.swift index 1b9ccaefb..03ae7dc70 100644 --- a/SignalServiceKit/src/Loki/API/LokiMessageWrapper.swift +++ b/SignalServiceKit/src/Loki/API/LokiMessageWrapper.swift @@ -1,6 +1,5 @@ -public class LokiMessageWrapper { - private init() {} +public enum LokiMessageWrapper { public enum WrappingError : LocalizedError { case failedToWrapData @@ -82,7 +81,7 @@ public class LokiMessageWrapper { /// - Parameter data: The data from the storage server (not base 64 encoded). /// - Returns: An `SSKProtoEnvelope` object. /// - Throws: A `WrappingError` if something went wrong. - static func unwrap(data: Data) throws -> SSKProtoEnvelope { + public static func unwrap(data: Data) throws -> SSKProtoEnvelope { do { let webSocketMessage = try WebSocketProtoWebSocketMessage.parseData(data) let envelope = webSocketMessage.request!.body! diff --git a/SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift b/SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift index 788edb2f4..593bad7fb 100644 --- a/SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift +++ b/SignalServiceKit/src/Loki/API/LokiP2PMessageHandler.swift @@ -1,36 +1,32 @@ -public class LokiP2PMessageHandler { +public final class LokiP2PMessageHandler { + private let messageReceiver = SSKEnvironment.shared.messageReceiver + + // MARK: Initialization public static let shared = LokiP2PMessageHandler() - - private var messageReceiver: OWSMessageReceiver { - return SSKEnvironment.shared.messageReceiver - } - private init() {} + private init() { } + // MARK: General public func handleReceivedMessage(base64EncodedData: String) { guard let data = Data(base64Encoded: base64EncodedData) else { - Logger.warn("[LokiP2PMessageHandler] Failed to decode p2p message data") + Logger.warn("[Loki] Failed to decode data for P2P message.") return } - guard let envelope = try? LokiMessageWrapper.unwrap(data: data) else { - Logger.warn("[LokiP2PMessageHandler] Failed to unwrap p2p data") + Logger.warn("[Loki] Failed to unwrap data for P2P message.") return } - - // We need to set the p2p field on the envelope + // We need to set the P2P field on the envelope let builder = envelope.asBuilder() builder.setIsPtpMessage(true) - - // Send it to message receiver + // Send it to the message receiver do { let newEnvelope = try builder.build() let envelopeData = try newEnvelope.serializedData() messageReceiver.handleReceivedEnvelopeData(envelopeData) } catch let error { - Logger.warn("[LokiP2PMessageHandler] Something went wrong while converting proto: \(error)") - owsFailDebug("Failed to build envelope") + Logger.warn("[Loki] Something went wrong during proto conversion: \(error).") } } diff --git a/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m b/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m index 3375379f4..cddf75886 100644 --- a/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m +++ b/SignalServiceKit/src/Loki/Messages/LKFriendRequestMessage.m @@ -8,10 +8,7 @@ - (BOOL)isFriendRequest { return YES; } -- (uint)ttl { - // Friend requests should stay for the longest on the storage server - return 4 * kDayInterval; -} +- (uint)ttl { return 4 * kDayInterval; } // Friend requests should stay for the longest on the storage server - (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient { SSKProtoContentBuilder *contentBuilder = [super contentBuilder:recipient]; diff --git a/SignalServiceKit/src/Loki/Messages/SSKProtoPrekeyBundleMessage+Loki.swift b/SignalServiceKit/src/Loki/Messages/SSKProtoPrekeyBundleMessage+Loki.swift index e907709b0..a951dfd00 100644 --- a/SignalServiceKit/src/Loki/Messages/SSKProtoPrekeyBundleMessage+Loki.swift +++ b/SignalServiceKit/src/Loki/Messages/SSKProtoPrekeyBundleMessage+Loki.swift @@ -1,7 +1,7 @@ @objc public extension SSKProtoPrekeyBundleMessage { - @objc public class func builder(fromPreKeyBundle preKeyBundle: PreKeyBundle) -> SSKProtoPrekeyBundleMessageBuilder { + @objc public static func builder(fromPreKeyBundle preKeyBundle: PreKeyBundle) -> SSKProtoPrekeyBundleMessageBuilder { let builder = self.builder() builder.setIdentityKey(preKeyBundle.identityKey) diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h index 598b30fa2..eca1b47e2 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.h @@ -141,10 +141,10 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) { @property (nonatomic, readonly) BOOL isOnline; -// Loki: Bool to indicate if proof of work is being calculated for this message +/// Loki: Bool to indicate if proof of work is being calculated for this message @property (atomic, readonly) BOOL isCalculatingPoW; -// Loki: Time to live for the message in seconds +/// Loki: Time to live for the message in seconds @property (nonatomic, readonly) uint ttl; /** diff --git a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m index 197c62fcf..7c8fd30ff 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSOutgoingMessage.m @@ -1155,7 +1155,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt } - (uint)ttl { - // Time to live for all messages should be 1 day + // Time to live for all messages (except friend request messages) should be 1 day // TODO: Change this to return a value that the user chose return 1 * kDayInterval; }