Merge branch 'mkirk/profile-censorship'

pull/1/head
Michael Kirk 8 years ago
commit 5ec9b40f10

@ -196,7 +196,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
- (AFHTTPSessionManager *)avatarHTTPManager - (AFHTTPSessionManager *)avatarHTTPManager
{ {
return [OWSSignalService sharedInstance].cdnSessionManager; return [OWSSignalService sharedInstance].CDNSessionManager;
} }
#pragma mark - User Profile Accessor #pragma mark - User Profile Accessor
@ -492,7 +492,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
success:^(NSURLSessionDataTask *task, id formResponseObject) { success:^(NSURLSessionDataTask *task, id formResponseObject) {
if (![formResponseObject isKindOfClass:[NSDictionary class]]) { if (![formResponseObject isKindOfClass:[NSDictionary class]]) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_response"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidResponse]);
failureBlock(); failureBlock();
return; return;
} }
@ -501,43 +501,43 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
NSString *formAcl = responseMap[@"acl"]; NSString *formAcl = responseMap[@"acl"];
if (![formAcl isKindOfClass:[NSString class]] || formAcl.length < 1) { if (![formAcl isKindOfClass:[NSString class]] || formAcl.length < 1) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_acl"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidAcl]);
failureBlock(); failureBlock();
return; return;
} }
NSString *formKey = responseMap[@"key"]; NSString *formKey = responseMap[@"key"];
if (![formKey isKindOfClass:[NSString class]] || formKey.length < 1) { if (![formKey isKindOfClass:[NSString class]] || formKey.length < 1) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_key"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidKey]);
failureBlock(); failureBlock();
return; return;
} }
NSString *formPolicy = responseMap[@"policy"]; NSString *formPolicy = responseMap[@"policy"];
if (![formPolicy isKindOfClass:[NSString class]] || formPolicy.length < 1) { if (![formPolicy isKindOfClass:[NSString class]] || formPolicy.length < 1) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_policy"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidPolicy]);
failureBlock(); failureBlock();
return; return;
} }
NSString *formAlgorithm = responseMap[@"algorithm"]; NSString *formAlgorithm = responseMap[@"algorithm"];
if (![formAlgorithm isKindOfClass:[NSString class]] || formAlgorithm.length < 1) { if (![formAlgorithm isKindOfClass:[NSString class]] || formAlgorithm.length < 1) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_algorithm"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidAlgorithm]);
failureBlock(); failureBlock();
return; return;
} }
NSString *formCredential = responseMap[@"credential"]; NSString *formCredential = responseMap[@"credential"];
if (![formCredential isKindOfClass:[NSString class]] || formCredential.length < 1) { if (![formCredential isKindOfClass:[NSString class]] || formCredential.length < 1) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_credential"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidCredential]);
failureBlock(); failureBlock();
return; return;
} }
NSString *formDate = responseMap[@"date"]; NSString *formDate = responseMap[@"date"];
if (![formDate isKindOfClass:[NSString class]] || formDate.length < 1) { if (![formDate isKindOfClass:[NSString class]] || formDate.length < 1) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_date"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidDate]);
failureBlock(); failureBlock();
return; return;
} }
NSString *formSignature = responseMap[@"signature"]; NSString *formSignature = responseMap[@"signature"];
if (![formSignature isKindOfClass:[NSString class]] || formSignature.length < 1) { if (![formSignature isKindOfClass:[NSString class]] || formSignature.length < 1) {
OWSProdFail(@"profile_manager_error_avatar_upload_form_invalid_signature"); OWSProdFail([OWSAnalyticsEvents profileManagerErrorAvatarUploadFormInvalidSignature]);
failureBlock(); failureBlock();
return; return;
} }
@ -571,22 +571,8 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
@"%@ avatar upload progress: %.2f%%", self.tag, uploadProgress.fractionCompleted * 100); @"%@ avatar upload progress: %.2f%%", self.tag, uploadProgress.fractionCompleted * 100);
} }
success:^(NSURLSessionDataTask *_Nonnull uploadTask, id _Nullable responseObject) { success:^(NSURLSessionDataTask *_Nonnull uploadTask, id _Nullable responseObject) {
OWSAssert([uploadTask.response isKindOfClass:[NSHTTPURLResponse class]]); DDLogDebug(@"%@ successfully uploaded avatar with key: %@", self.tag, formKey);
NSHTTPURLResponse *response = (NSHTTPURLResponse *)uploadTask.response; successBlock(formKey);
// 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);
} }
failure:^(NSURLSessionDataTask *_Nullable uploadTask, NSError *_Nonnull error) { failure:^(NSURLSessionDataTask *_Nullable uploadTask, NSError *_Nonnull error) {
DDLogVerbose(@"%@ uploading avatar failed with error: %@", self.tag, error); DDLogVerbose(@"%@ uploading avatar failed with error: %@", self.tag, error);

@ -9,7 +9,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSCensorshipConfiguration : NSObject @interface OWSCensorshipConfiguration : NSObject
- (NSString *)frontingHost:(NSString *)e164PhoneNumber; - (NSString *)frontingHost:(NSString *)e164PhoneNumber;
- (NSString *)reflectorHost; - (NSString *)signalServiceReflectorHost;
- (NSString *)CDNReflectorHost;
- (BOOL)isCensoredPhoneNumber:(NSString *)e164PhoneNumber; - (BOOL)isCensoredPhoneNumber:(NSString *)e164PhoneNumber;
@end @end

@ -3,12 +3,11 @@
// //
#import "OWSCensorshipConfiguration.h" #import "OWSCensorshipConfiguration.h"
#import "TSConstants.h"
#import "TSStorageManager.h" #import "TSStorageManager.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
NSString *const OWSCensorshipConfigurationReflectorHost = @"signal-reflector-meek.appspot.com";
@implementation OWSCensorshipConfiguration @implementation OWSCensorshipConfiguration
- (NSString *)frontingHost:(NSString *)e164PhoneNumber - (NSString *)frontingHost:(NSString *)e164PhoneNumber
@ -32,9 +31,14 @@ NSString *const OWSCensorshipConfigurationReflectorHost = @"signal-reflector-mee
return [@"https://" stringByAppendingString:domain]; return [@"https://" stringByAppendingString:domain];
} }
- (NSString *)reflectorHost - (NSString *)signalServiceReflectorHost
{
return textSecureServiceReflectorHost;
}
- (NSString *)CDNReflectorHost
{ {
return OWSCensorshipConfigurationReflectorHost; return textSecureCDNReflectorHost;
} }
- (NSDictionary<NSString *, NSString *> *)censoredCountryCodes - (NSDictionary<NSString *, NSString *> *)censoredCountryCodes
@ -49,7 +53,7 @@ NSString *const OWSCensorshipConfigurationReflectorHost = @"signal-reflector-mee
// //
// a) Add the appropriate pinning certificate(s) in // a) Add the appropriate pinning certificate(s) in
// SignalServiceKit.podspec. // SignalServiceKit.podspec.
// b) Update reflectorHost accordingly. // b) Update signalServiceReflectorHost accordingly.
return @{ return @{
// Egypt // Egypt
@"+20": @"google.com.eg", @"+20": @"google.com.eg",

@ -16,7 +16,7 @@ extern NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidCha
@property (nonatomic, readonly) AFHTTPSessionManager *signalServiceSessionManager; @property (nonatomic, readonly) AFHTTPSessionManager *signalServiceSessionManager;
/// For uploading avatar assets. /// For uploading avatar assets.
@property (nonatomic, readonly) AFHTTPSessionManager *cdnSessionManager; @property (nonatomic, readonly) AFHTTPSessionManager *CDNSessionManager;
@property (atomic, readonly) BOOL isCensorshipCircumventionActive; @property (atomic, readonly) BOOL isCensorshipCircumventionActive;

@ -179,7 +179,7 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange =
return sessionManager; return sessionManager;
} }
- (AFHTTPSessionManager *)reflectorSignalServiceSessionManager - (NSURL *)domainFrontingBaseURL
{ {
NSString *localNumber = [TSAccountManager localNumber]; NSString *localNumber = [TSAccountManager localNumber];
OWSAssert(localNumber.length > 0); OWSAssert(localNumber.length > 0);
@ -192,14 +192,20 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange =
}; };
NSURL *baseURL = [[NSURL alloc] initWithString:[self.censorshipConfiguration frontingHost:localNumber]]; NSURL *baseURL = [[NSURL alloc] initWithString:[self.censorshipConfiguration frontingHost:localNumber]];
OWSAssert(baseURL); OWSAssert(baseURL);
return baseURL;
}
- (AFHTTPSessionManager *)reflectorSignalServiceSessionManager
{
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration; NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
AFHTTPSessionManager *sessionManager = AFHTTPSessionManager *sessionManager =
[[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:sessionConf]; [[AFHTTPSessionManager alloc] initWithBaseURL:self.domainFrontingBaseURL sessionConfiguration:sessionConf];
sessionManager.securityPolicy = [[self class] googlePinningPolicy]; sessionManager.securityPolicy = [[self class] googlePinningPolicy];
sessionManager.requestSerializer = [AFJSONRequestSerializer serializer]; sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
[sessionManager.requestSerializer setValue:self.censorshipConfiguration.reflectorHost forHTTPHeaderField:@"Host"]; [sessionManager.requestSerializer setValue:self.censorshipConfiguration.signalServiceReflectorHost forHTTPHeaderField:@"Host"];
sessionManager.responseSerializer = [AFJSONResponseSerializer serializer]; sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
@ -208,12 +214,18 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange =
#pragma mark - Profile Uploading #pragma mark - Profile Uploading
- (AFHTTPSessionManager *)cdnSessionManager - (AFHTTPSessionManager *)CDNSessionManager
{ {
if (self.isCensorshipCircumventionActive) { 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]; NSURL *baseURL = [[NSURL alloc] initWithString:textSecureCDNServerURL];
OWSAssert(baseURL); OWSAssert(baseURL);
@ -229,6 +241,22 @@ NSString *const kNSNotificationName_IsCensorshipCircumventionActiveDidChange =
return sessionManager; 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 #pragma mark - Google Pinning Policy
/** /**

@ -24,15 +24,21 @@ typedef enum { kSMSVerification, kPhoneNumberVerification } VerificationTranspor
#ifndef DEBUG #ifndef DEBUG
// Production
#define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/" #define textSecureWebSocketAPI @"wss://textsecure-service.whispersystems.org/v1/websocket/"
#define textSecureServerURL @"https://textsecure-service.whispersystems.org/" #define textSecureServerURL @"https://textsecure-service.whispersystems.org/"
#define textSecureCDNServerURL @"https://cdn.signal.org" #define textSecureCDNServerURL @"https://cdn.signal.org"
#define textSecureServiceReflectorHost @"signal-reflector-meek.appspot.com"
#define textSecureCDNReflectorHost @"signal-cdn-reflector.appspot.com"
#else #else
// Staging
#define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/" #define textSecureWebSocketAPI @"wss://textsecure-service-staging.whispersystems.org/v1/websocket/"
#define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/" #define textSecureServerURL @"https://textsecure-service-staging.whispersystems.org/"
#define textSecureCDNServerURL @"https://cdn-staging.signal.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 #endif

@ -176,6 +176,22 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSString *)prekeysDeletedOldUnacceptedSignedPrekey; + (NSString *)prekeysDeletedOldUnacceptedSignedPrekey;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidAcl;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidAlgorithm;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidCredential;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidDate;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidKey;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidPolicy;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidResponse;
+ (NSString *)profileManagerErrorAvatarUploadFormInvalidSignature;
+ (NSString *)registrationBegan; + (NSString *)registrationBegan;
+ (NSString *)registrationRegisteredPhoneNumber; + (NSString *)registrationRegisteredPhoneNumber;

@ -422,6 +422,46 @@ NS_ASSUME_NONNULL_BEGIN
return @"prekeys_deleted_old_unaccepted_signed_prekey"; 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 + (NSString *)registrationBegan
{ {
return @"registration_began"; return @"registration_began";

Loading…
Cancel
Save