mirror of https://github.com/oxen-io/session-ios
WIP: Censorship circumvention in Egypt and UAE
* non-websocket message fetching // FREEBIEpull/1/head
parent
5ccbd4ca6d
commit
f1ade83c3f
@ -0,0 +1,14 @@
|
||||
// Created by Michael Kirk on 12/19/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "TSRequest.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSAcknowledgeMessageDeliveryRequest : TSRequest
|
||||
|
||||
- (instancetype)initWithSource:(NSString *)source timestamp:(UInt64)timestamp;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,23 @@
|
||||
// Created by Michael Kirk on 12/19/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSAcknowledgeMessageDeliveryRequest.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation OWSAcknowledgeMessageDeliveryRequest
|
||||
|
||||
- (instancetype)initWithSource:(NSString *)source timestamp:(UInt64)timestamp
|
||||
{
|
||||
NSString *path = [NSString stringWithFormat:@"v1/messages/%@/%llu", source, timestamp];
|
||||
NSURL *url = [NSURL URLWithString:path];
|
||||
|
||||
self = [super initWithURL:url];
|
||||
self.HTTPMethod = @"DELETE";
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,12 @@
|
||||
// Created by Michael Kirk on 12/19/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "TSRequest.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSGetMessagesRequest : TSRequest
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,18 @@
|
||||
// Created by Michael Kirk on 12/19/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSGetMessagesRequest.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation OWSGetMessagesRequest
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
NSURL *url = [NSURL URLWithString:@"v1/messages"];
|
||||
return [super initWithURL:url];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,16 @@
|
||||
// Created by Michael Kirk on 12/20/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSStorageManager;
|
||||
|
||||
@interface OWSCensorshipConfiguration : NSObject
|
||||
|
||||
- (NSString *)frontingHost;
|
||||
- (NSString *)reflectorHost;
|
||||
- (BOOL)isCensoredPhoneNumber:(NSString *)e164PhonNumber;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,57 @@
|
||||
// Created by Michael Kirk on 12/20/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSCensorshipConfiguration.h"
|
||||
#import "TSStorageManager.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *const OWSCensorshipConfigurationFrontingHost = @"https://google.com";
|
||||
NSString *const OWSCensorshipConfigurationReflectorHost = @"signal-reflector-meek.appspot.com";
|
||||
|
||||
@implementation OWSCensorshipConfiguration
|
||||
|
||||
- (NSString *)frontingHost
|
||||
{
|
||||
return OWSCensorshipConfigurationFrontingHost;
|
||||
}
|
||||
|
||||
- (NSString *)reflectorHost
|
||||
{
|
||||
return OWSCensorshipConfigurationReflectorHost;
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)censoredCountryCodes
|
||||
{
|
||||
// Reports of censorship in:
|
||||
// Egypt
|
||||
// UAE
|
||||
return @[@"+20",
|
||||
@"+971"];
|
||||
}
|
||||
|
||||
- (BOOL)isCensoredPhoneNumber:(NSString *)e164PhonNumber
|
||||
{
|
||||
for (NSString *countryCode in self.censoredCountryCodes) {
|
||||
if ([e164PhonNumber hasPrefix:countryCode]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
||||
+ (NSString *)tag
|
||||
{
|
||||
return [NSString stringWithFormat:@"[%@]", self.class];
|
||||
}
|
||||
|
||||
- (NSString *)tag
|
||||
{
|
||||
return self.class.tag;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,18 @@
|
||||
// Created by Michael Kirk on 12/20/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSStorageManager;
|
||||
@class AFHTTPSessionManager;
|
||||
|
||||
@interface OWSSignalService : NSObject
|
||||
|
||||
- (instancetype)initWithStorageManager:(TSStorageManager *)storageManager;
|
||||
|
||||
@property (nonatomic, readonly) BOOL isCensored;
|
||||
@property (nonatomic, readonly) AFHTTPSessionManager *HTTPSessionManager;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,129 @@
|
||||
// Created by Michael Kirk on 12/20/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSSignalService.h"
|
||||
#import "OWSCensorshipConfiguration.h"
|
||||
#import "OWSHTTPSecurityPolicy.h"
|
||||
#import "TSConstants.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSStorageManager+keyingMaterial.h"
|
||||
#import <AFNetworking/AFHTTPSessionManager.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TSAccountManager (OWSSignalService)
|
||||
|
||||
@property (nullable, nonatomic, readonly) NSString *phoneNumberAwaitingVerification;
|
||||
|
||||
@end
|
||||
|
||||
@interface OWSSignalService ()
|
||||
|
||||
@property (nonatomic, readonly, strong) TSStorageManager *storageManager;
|
||||
@property (nonatomic, readonly, strong) TSAccountManager *tsAccountManager;
|
||||
@property (nonatomic, readonly, strong) OWSCensorshipConfiguration *censorshipConfiguration;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSSignalService
|
||||
|
||||
- (instancetype)initWithStorageManager:(TSStorageManager *)storageManager
|
||||
tsAccountManager:(TSAccountManager *)tsAccountManager
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_storageManager = storageManager;
|
||||
_tsAccountManager = tsAccountManager;
|
||||
_censorshipConfiguration = [OWSCensorshipConfiguration new];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isCensored
|
||||
{
|
||||
|
||||
NSString *localNumber = self.storageManager.localNumber;
|
||||
NSString *pendingNumber = self.tsAccountManager.phoneNumberAwaitingVerification;
|
||||
|
||||
if (localNumber) {
|
||||
if ([self.censorshipConfiguration isCensoredPhoneNumber:localNumber]) {
|
||||
DDLogInfo(@"%@ assumed censorship for localNumber: %@", self.tag, localNumber);
|
||||
return YES;
|
||||
} else {
|
||||
DDLogInfo(@"%@ assumed no censorship for localNumber: %@", self.tag, localNumber);
|
||||
return NO;
|
||||
}
|
||||
} else if (pendingNumber) {
|
||||
if ([self.censorshipConfiguration isCensoredPhoneNumber:pendingNumber]) {
|
||||
DDLogInfo(@"%@ assumed censorship for pending Number: %@", self.tag, pendingNumber);
|
||||
return YES;
|
||||
} else {
|
||||
DDLogInfo(@"%@ assumed no censorship for pending Number: %@", self.tag, pendingNumber);
|
||||
return NO;
|
||||
}
|
||||
} else {
|
||||
DDLogError(@"no known phone number to check for censorship.");
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (AFHTTPSessionManager *)HTTPSessionManager
|
||||
{
|
||||
if (self.isCensored) {
|
||||
return self.reflectorHTTPSessionManager;
|
||||
} else {
|
||||
return self.defaultHTTPSessionManager;
|
||||
}
|
||||
}
|
||||
|
||||
- (AFHTTPSessionManager *)defaultHTTPSessionManager
|
||||
{
|
||||
NSURL *baseURL = [[NSURL alloc] initWithString:textSecureServerURL];
|
||||
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
|
||||
AFHTTPSessionManager *sessionManager =
|
||||
[[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:sessionConf];
|
||||
|
||||
sessionManager.securityPolicy = [OWSHTTPSecurityPolicy sharedPolicy];
|
||||
sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
- (AFHTTPSessionManager *)reflectorHTTPSessionManager
|
||||
{
|
||||
// Target fronting domain
|
||||
NSURL *baseURL = [[NSURL alloc] initWithString:self.censorshipConfiguration.frontingHost];
|
||||
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
|
||||
AFHTTPSessionManager *sessionManager =
|
||||
[[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:sessionConf];
|
||||
|
||||
// FIXME TODO can we still pin SSL while fronting?
|
||||
// sessionManager.securityPolicy = [OWSHTTPSecurityPolicy sharedPolicy];
|
||||
|
||||
sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
[sessionManager.requestSerializer setValue:self.censorshipConfiguration.reflectorHost forHTTPHeaderField:@"Host"];
|
||||
|
||||
sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
||||
+ (NSString *)tag
|
||||
{
|
||||
return [NSString stringWithFormat:@"[%@]", self.class];
|
||||
}
|
||||
|
||||
- (NSString *)tag
|
||||
{
|
||||
return self.class.tag;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
Loading…
Reference in New Issue