From 251e206b6dc00d148f67dec6662fdf7dc5918128 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Thu, 24 Aug 2017 22:37:45 -0400 Subject: [PATCH 1/2] profiles vs. censorship circumvention // FREEBIE --- Signal/src/Profiles/OWSProfileManager.m | 20 ++-------- .../src/Network/OWSCensorshipConfiguration.h | 3 +- .../src/Network/OWSCensorshipConfiguration.m | 14 ++++--- .../src/Network/OWSSignalService.h | 2 +- .../src/Network/OWSSignalService.m | 38 ++++++++++++++++--- SignalServiceKit/src/TSConstants.h | 6 +++ 6 files changed, 54 insertions(+), 29 deletions(-) diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index 7dc1ac6808..898eebef71 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -196,7 +196,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; - (AFHTTPSessionManager *)avatarHTTPManager { - return [OWSSignalService sharedInstance].cdnSessionManager; + return [OWSSignalService sharedInstance].CDNSessionManager; } #pragma mark - User Profile Accessor @@ -571,22 +571,8 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; @"%@ avatar upload progress: %.2f%%", self.tag, uploadProgress.fractionCompleted * 100); } success:^(NSURLSessionDataTask *_Nonnull uploadTask, id _Nullable responseObject) { - OWSAssert([uploadTask.response isKindOfClass:[NSHTTPURLResponse class]]); - NSHTTPURLResponse *response = (NSHTTPURLResponse *)uploadTask.response; - - // We could also construct this URL locally from manager.baseUrl + formKey - // but the approach of getting it from the remote provider seems a more - // robust way to ensure we've actually created the resource where we - // think we have. - NSString *avatarUrlPath = response.allHeaderFields[@"Location"]; - if (avatarUrlPath.length == 0) { - OWSProdFail(@"profile_manager_error_avatar_upload_no_location_in_response"); - failureBlock(); - return; - } - - DDLogVerbose(@"%@ successfully uploaded avatar url: %@", self.tag, avatarUrlPath); - successBlock(avatarUrlPath); + DDLogDebug(@"%@ successfully uploaded avatar with key: %@", self.tag, formKey); + successBlock(formKey); } failure:^(NSURLSessionDataTask *_Nullable uploadTask, NSError *_Nonnull error) { DDLogVerbose(@"%@ uploading avatar failed with error: %@", self.tag, error); diff --git a/SignalServiceKit/src/Network/OWSCensorshipConfiguration.h b/SignalServiceKit/src/Network/OWSCensorshipConfiguration.h index a399a41d2b..1807fcf02c 100644 --- a/SignalServiceKit/src/Network/OWSCensorshipConfiguration.h +++ b/SignalServiceKit/src/Network/OWSCensorshipConfiguration.h @@ -9,7 +9,8 @@ NS_ASSUME_NONNULL_BEGIN @interface OWSCensorshipConfiguration : NSObject - (NSString *)frontingHost:(NSString *)e164PhoneNumber; -- (NSString *)reflectorHost; +- (NSString *)signalServiceReflectorHost; +- (NSString *)CDNReflectorHost; - (BOOL)isCensoredPhoneNumber:(NSString *)e164PhoneNumber; @end diff --git a/SignalServiceKit/src/Network/OWSCensorshipConfiguration.m b/SignalServiceKit/src/Network/OWSCensorshipConfiguration.m index ad5431946f..e89880c332 100644 --- a/SignalServiceKit/src/Network/OWSCensorshipConfiguration.m +++ b/SignalServiceKit/src/Network/OWSCensorshipConfiguration.m @@ -3,12 +3,11 @@ // #import "OWSCensorshipConfiguration.h" +#import "TSConstants.h" #import "TSStorageManager.h" NS_ASSUME_NONNULL_BEGIN -NSString *const OWSCensorshipConfigurationReflectorHost = @"signal-reflector-meek.appspot.com"; - @implementation OWSCensorshipConfiguration - (NSString *)frontingHost:(NSString *)e164PhoneNumber @@ -32,9 +31,14 @@ NSString *const OWSCensorshipConfigurationReflectorHost = @"signal-reflector-mee return [@"https://" stringByAppendingString:domain]; } -- (NSString *)reflectorHost +- (NSString *)signalServiceReflectorHost { - return OWSCensorshipConfigurationReflectorHost; + return textSecureServiceReflectorHost; +} + +- (NSString *)CDNReflectorHost +{ + return textSecureCDNReflectorHost; } - (NSDictionary *)censoredCountryCodes @@ -49,7 +53,7 @@ NSString *const OWSCensorshipConfigurationReflectorHost = @"signal-reflector-mee // // a) Add the appropriate pinning certificate(s) in // SignalServiceKit.podspec. - // b) Update reflectorHost accordingly. + // b) Update signalServiceReflectorHost accordingly. return @{ // Egypt @"+20": @"google.com.eg", diff --git a/SignalServiceKit/src/Network/OWSSignalService.h b/SignalServiceKit/src/Network/OWSSignalService.h index 7b333f93a4..65db781bb6 100644 --- a/SignalServiceKit/src/Network/OWSSignalService.h +++ b/SignalServiceKit/src/Network/OWSSignalService.h @@ -16,7 +16,7 @@ extern NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidCha @property (nonatomic, readonly) AFHTTPSessionManager *signalServiceSessionManager; /// For uploading avatar assets. -@property (nonatomic, readonly) AFHTTPSessionManager *cdnSessionManager; +@property (nonatomic, readonly) AFHTTPSessionManager *CDNSessionManager; @property (atomic, readonly) BOOL isCensorshipCircumventionActive; diff --git a/SignalServiceKit/src/Network/OWSSignalService.m b/SignalServiceKit/src/Network/OWSSignalService.m index d9e7020822..2568dbf8e2 100644 --- a/SignalServiceKit/src/Network/OWSSignalService.m +++ b/SignalServiceKit/src/Network/OWSSignalService.m @@ -179,7 +179,7 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange = return sessionManager; } -- (AFHTTPSessionManager *)reflectorSignalServiceSessionManager +- (NSURL *)domainFrontingBaseURL { NSString *localNumber = [TSAccountManager localNumber]; OWSAssert(localNumber.length > 0); @@ -192,14 +192,20 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange = }; NSURL *baseURL = [[NSURL alloc] initWithString:[self.censorshipConfiguration frontingHost:localNumber]]; OWSAssert(baseURL); + + return baseURL; +} + +- (AFHTTPSessionManager *)reflectorSignalServiceSessionManager +{ NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration; AFHTTPSessionManager *sessionManager = - [[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:sessionConf]; + [[AFHTTPSessionManager alloc] initWithBaseURL:self.domainFrontingBaseURL sessionConfiguration:sessionConf]; sessionManager.securityPolicy = [[self class] googlePinningPolicy]; sessionManager.requestSerializer = [AFJSONRequestSerializer serializer]; - [sessionManager.requestSerializer setValue:self.censorshipConfiguration.reflectorHost forHTTPHeaderField:@"Host"]; + [sessionManager.requestSerializer setValue:self.censorshipConfiguration.signalServiceReflectorHost forHTTPHeaderField:@"Host"]; sessionManager.responseSerializer = [AFJSONResponseSerializer serializer]; @@ -208,12 +214,18 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange = #pragma mark - Profile Uploading -- (AFHTTPSessionManager *)cdnSessionManager +- (AFHTTPSessionManager *)CDNSessionManager { if (self.isCensorshipCircumventionActive) { - DDLogInfo(@"%@ Profile uploading may not work when under censorship.", self.tag); + DDLogInfo(@"%@ using reflector CDNSessionManager", self.tag); + return self.reflectorCDNSessionManager; + } else { + return self.defaultCDNSessionManager; } +} +- (AFHTTPSessionManager *)defaultCDNSessionManager +{ NSURL *baseURL = [[NSURL alloc] initWithString:textSecureCDNServerURL]; OWSAssert(baseURL); @@ -229,6 +241,22 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange = return sessionManager; } +- (AFHTTPSessionManager *)reflectorCDNSessionManager +{ + NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration; + AFHTTPSessionManager *sessionManager = + [[AFHTTPSessionManager alloc] initWithBaseURL:self.domainFrontingBaseURL sessionConfiguration:sessionConf]; + + sessionManager.securityPolicy = [[self class] googlePinningPolicy]; + + sessionManager.requestSerializer = [AFJSONRequestSerializer serializer]; + [sessionManager.requestSerializer setValue:self.censorshipConfiguration.CDNReflectorHost forHTTPHeaderField:@"Host"]; + + sessionManager.responseSerializer = [AFJSONResponseSerializer serializer]; + + return sessionManager; +} + #pragma mark - Google Pinning Policy /** diff --git a/SignalServiceKit/src/TSConstants.h b/SignalServiceKit/src/TSConstants.h index 7e86ed9ac2..378aa3b53d 100644 --- a/SignalServiceKit/src/TSConstants.h +++ b/SignalServiceKit/src/TSConstants.h @@ -24,15 +24,21 @@ typedef enum { kSMSVerification, kPhoneNumberVerification } VerificationTranspor #ifndef DEBUG +// Production #define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/" #define textSecureServerURL @"https://textsecure-service.whispersystems.org/" #define textSecureCDNServerURL @"https://cdn.signal.org" +#define textSecureServiceReflectorHost @"signal-reflector-meek.appspot.com" +#define textSecureCDNReflectorHost @"signal-cdn-reflector.appspot.com" #else +// Staging #define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/" #define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/" #define textSecureCDNServerURL @"https://cdn-staging.signal.org" +#define textSecureServiceReflectorHost @"meek-signal-service-staging.appspot.com"; +#define textSecureCDNReflectorHost @"meek-signal-cdn-staging.appspot.com"; #endif From 1e51bf48995005335a54eabe55f4b4439fefc85d Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Fri, 25 Aug 2017 17:19:31 -0400 Subject: [PATCH 2/2] extract event names // FREEBIE --- Signal/src/Profiles/OWSProfileManager.m | 16 ++++---- .../src/Util/OWSAnalyticsEvents.h | 16 ++++++++ .../src/Util/OWSAnalyticsEvents.m | 40 +++++++++++++++++++ 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index 898eebef71..a3f304fbc5 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -492,7 +492,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; success:^(NSURLSessionDataTask *task, id formResponseObject) { if (![formResponseObject isKindOfClass:[NSDictionary class]]) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_response"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidResponse]); failureBlock(); return; } @@ -501,43 +501,43 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; NSString *formAcl = responseMap[@"acl"]; if (![formAcl isKindOfClass:[NSString class]] || formAcl.length < 1) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_acl"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidAcl]); failureBlock(); return; } NSString *formKey = responseMap[@"key"]; if (![formKey isKindOfClass:[NSString class]] || formKey.length < 1) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_key"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidKey]); failureBlock(); return; } NSString *formPolicy = responseMap[@"policy"]; if (![formPolicy isKindOfClass:[NSString class]] || formPolicy.length < 1) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_policy"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidPolicy]); failureBlock(); return; } NSString *formAlgorithm = responseMap[@"algorithm"]; if (![formAlgorithm isKindOfClass:[NSString class]] || formAlgorithm.length < 1) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_algorithm"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidAlgorithm]); failureBlock(); return; } NSString *formCredential = responseMap[@"credential"]; if (![formCredential isKindOfClass:[NSString class]] || formCredential.length < 1) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_credential"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidCredential]); failureBlock(); return; } NSString *formDate = responseMap[@"date"]; if (![formDate isKindOfClass:[NSString class]] || formDate.length < 1) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_date"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidDate]); failureBlock(); return; } NSString *formSignature = responseMap[@"signature"]; if (![formSignature isKindOfClass:[NSString class]] || formSignature.length < 1) { - OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_signature"); + OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidSignature]); failureBlock(); return; } diff --git a/SignalServiceKit/src/Util/OWSAnalyticsEvents.h b/SignalServiceKit/src/Util/OWSAnalyticsEvents.h index a8b02e0193..c331230f22 100755 --- a/SignalServiceKit/src/Util/OWSAnalyticsEvents.h +++ b/SignalServiceKit/src/Util/OWSAnalyticsEvents.h @@ -176,6 +176,22 @@ NS_ASSUME_NONNULL_BEGIN + (NSString *)prekeysDeletedOldUnacceptedSignedPrekey; ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidAcl; + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidAlgorithm; + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidCredential; + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidDate; + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidKey; + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidPolicy; + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidResponse; + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidSignature; + + (NSString *)registrationBegan; + (NSString *)registrationRegisteredPhoneNumber; diff --git a/SignalServiceKit/src/Util/OWSAnalyticsEvents.m b/SignalServiceKit/src/Util/OWSAnalyticsEvents.m index 58900d8776..2653b9a8b6 100755 --- a/SignalServiceKit/src/Util/OWSAnalyticsEvents.m +++ b/SignalServiceKit/src/Util/OWSAnalyticsEvents.m @@ -422,6 +422,46 @@ NS_ASSUME_NONNULL_BEGIN return @"prekeys_deleted_old_unaccepted_signed_prekey"; } ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidAcl +{ + return @"profile_manager_error_avatar_upload_form_invalid_acl"; +} + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidAlgorithm +{ + return @"profile_manager_error_avatar_upload_form_invalid_algorithm"; +} + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidCredential +{ + return @"profile_manager_error_avatar_upload_form_invalid_credential"; +} + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidDate +{ + return @"profile_manager_error_avatar_upload_form_invalid_date"; +} + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidKey +{ + return @"profile_manager_error_avatar_upload_form_invalid_key"; +} + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidPolicy +{ + return @"profile_manager_error_avatar_upload_form_invalid_policy"; +} + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidResponse +{ + return @"profile_manager_error_avatar_upload_form_invalid_response"; +} + ++ (NSString *)profileManagerErrorAvatarUploadFormInvalidSignature +{ + return @"profile_manager_error_avatar_upload_form_invalid_signature"; +} + + (NSString *)registrationBegan { return @"registration_began";