mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Censorship circumvention in Egypt and UAE
* domain fronting * non-websocket message fetching * alternate pinning policy for google hosted reflector server // FREEBIE
This commit is contained in:
parent
b1ebfa9873
commit
78515377b1
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
# Xcode
|
||||
#
|
||||
.DS_Store
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "SignalServiceKit"
|
||||
s.version = "0.8.1"
|
||||
s.version = "0.9.0"
|
||||
s.summary = "An Objective-C library for communicating with the Signal messaging service."
|
||||
|
||||
s.description = <<-DESC
|
||||
|
@ -27,7 +27,8 @@ An Objective-C library for communicating with the Signal messaging service.
|
|||
s.requires_arc = true
|
||||
s.source_files = 'src/**/*.{h,m,mm}'
|
||||
|
||||
s.resource = 'src/Security/PinningCertificate/textsecure.cer'
|
||||
s.resources = ['src/Security/PinningCertificate/textsecure.cer',
|
||||
'src/Security/PinningCertificate/GIAG2.crt']
|
||||
s.prefix_header_file = 'src/TSPrefix.h'
|
||||
s.xcconfig = { 'OTHER_CFLAGS' => '$(inherited) -DSQLITE_HAS_CODEC' }
|
||||
|
||||
|
|
|
@ -139,6 +139,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return;
|
||||
}
|
||||
|
||||
TSAccountManager *manager = [self sharedInstance];
|
||||
manager.phoneNumberAwaitingVerification = phoneNumber;
|
||||
|
||||
[[TSNetworkManager sharedManager]
|
||||
makeRequest:[[TSRequestVerificationCodeRequest alloc]
|
||||
initWithPhoneNumber:phoneNumber
|
||||
|
@ -148,8 +151,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.tag,
|
||||
phoneNumber,
|
||||
isSMS ? @"SMS" : @"Voice");
|
||||
TSAccountManager *manager = [self sharedInstance];
|
||||
manager.phoneNumberAwaitingVerification = phoneNumber;
|
||||
successBlock();
|
||||
}
|
||||
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||
|
|
|
@ -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
|
12
src/Network/API/Requests/OWSGetMessagesRequest.h
Normal file
12
src/Network/API/Requests/OWSGetMessagesRequest.h
Normal file
|
@ -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
|
18
src/Network/API/Requests/OWSGetMessagesRequest.m
Normal file
18
src/Network/API/Requests/OWSGetMessagesRequest.m
Normal file
|
@ -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
|
|
@ -34,6 +34,6 @@
|
|||
|
||||
- (void)makeRequest:(TSRequest *)request
|
||||
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure;
|
||||
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure NS_SWIFT_NAME(makeRequest(_:success:failure:));
|
||||
|
||||
@end
|
||||
|
|
|
@ -6,22 +6,19 @@
|
|||
// Copyright (c) 2013 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <AFNetworking/AFNetworking.h>
|
||||
|
||||
#import "OWSHTTPSecurityPolicy.h"
|
||||
|
||||
#import "NSURLSessionDataTask+StatusCode.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSNetworkManager.h"
|
||||
#import "NSURLSessionDataTask+StatusCode.h"
|
||||
#import "OWSSignalService.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSStorageManager+keyingMaterial.h"
|
||||
#import "TSVerifyCodeRequest.h"
|
||||
#import <AFNetworking/AFNetworking.h>
|
||||
|
||||
#define TSNetworkManagerDomain @"org.whispersystems.signal.networkManager"
|
||||
|
||||
@interface TSNetworkManager ()
|
||||
|
||||
@property AFHTTPSessionManager *operationManager;
|
||||
|
||||
@property (nonatomic, readonly, strong) OWSSignalService *signalService;
|
||||
typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
|
||||
|
||||
@end
|
||||
|
@ -34,30 +31,21 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
|
|||
static TSNetworkManager *sharedMyManager = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedMyManager = [[self alloc] initWithDefaultOperationManager];
|
||||
OWSSignalService *signalService = [[OWSSignalService alloc] init];
|
||||
sharedMyManager = [[self alloc] initWithSignalService:signalService];
|
||||
});
|
||||
return sharedMyManager;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDefaultOperationManager
|
||||
{
|
||||
NSURLSessionConfiguration *sessionConf = NSURLSessionConfiguration.ephemeralSessionConfiguration;
|
||||
NSURL *baseURL = [[NSURL alloc] initWithString:textSecureServerURL];
|
||||
AFHTTPSessionManager *operationManager =
|
||||
[[AFHTTPSessionManager alloc] initWithBaseURL:baseURL sessionConfiguration:sessionConf];
|
||||
operationManager.securityPolicy = [OWSHTTPSecurityPolicy sharedPolicy];
|
||||
|
||||
return [self initWithOperationManager:operationManager];
|
||||
}
|
||||
|
||||
- (instancetype)initWithOperationManager:(AFHTTPSessionManager *)operationManager
|
||||
- (instancetype)initWithSignalService:(OWSSignalService *)signalService
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_operationManager = operationManager;
|
||||
_signalService = signalService;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -73,48 +61,44 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
|
|||
void (^failure)(NSURLSessionDataTask *task, NSError *error) =
|
||||
[TSNetworkManager errorPrettifyingForFailureBlock:failureBlock];
|
||||
|
||||
self.operationManager.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
self.operationManager.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
AFHTTPSessionManager *sessionManager = self.signalService.HTTPSessionManager;
|
||||
|
||||
if ([request isKindOfClass:[TSVerifyCodeRequest class]]) {
|
||||
// We plant the Authorization parameter ourselves, no need to double add.
|
||||
[self.operationManager.requestSerializer
|
||||
[sessionManager.requestSerializer
|
||||
setAuthorizationHeaderFieldWithUsername:((TSVerifyCodeRequest *)request).numberToValidate
|
||||
password:[request.parameters objectForKey:@"AuthKey"]];
|
||||
[request.parameters removeObjectForKey:@"AuthKey"];
|
||||
[self.operationManager PUT:[textSecureServerURL stringByAppendingString:request.URL.absoluteString]
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
[sessionManager PUT:request.URL.absoluteString parameters:request.parameters success:success failure:failure];
|
||||
} else {
|
||||
if (![request isKindOfClass:[TSRequestVerificationCodeRequest class]]) {
|
||||
[self.operationManager.requestSerializer
|
||||
[sessionManager.requestSerializer
|
||||
setAuthorizationHeaderFieldWithUsername:[TSAccountManager localNumber]
|
||||
password:[TSStorageManager serverAuthToken]];
|
||||
}
|
||||
|
||||
if ([request.HTTPMethod isEqualToString:@"GET"]) {
|
||||
[self.operationManager GET:[textSecureServerURL stringByAppendingString:request.URL.absoluteString]
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
[sessionManager GET:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"POST"]) {
|
||||
[self.operationManager POST:[textSecureServerURL stringByAppendingString:request.URL.absoluteString]
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
[sessionManager POST:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
progress:nil
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"PUT"]) {
|
||||
[self.operationManager PUT:[textSecureServerURL stringByAppendingString:request.URL.absoluteString]
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
[sessionManager PUT:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
} else if ([request.HTTPMethod isEqualToString:@"DELETE"]) {
|
||||
[self.operationManager DELETE:[textSecureServerURL stringByAppendingString:request.URL.absoluteString]
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
[sessionManager DELETE:request.URL.absoluteString
|
||||
parameters:request.parameters
|
||||
success:success
|
||||
failure:failure];
|
||||
} else {
|
||||
DDLogError(@"Trying to perform HTTP operation with unknown verb: %@", request.HTTPMethod);
|
||||
}
|
||||
|
@ -243,6 +227,8 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error);
|
|||
return [NSError errorWithDomain:TSNetworkManagerDomain code:code userInfo:dict];
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
||||
+ (NSString *)tag
|
||||
{
|
||||
return [NSString stringWithFormat:@"[%@]", self.class];
|
||||
|
|
16
src/Network/OWSCensorshipConfiguration.h
Normal file
16
src/Network/OWSCensorshipConfiguration.h
Normal file
|
@ -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
|
57
src/Network/OWSCensorshipConfiguration.m
Normal file
57
src/Network/OWSCensorshipConfiguration.m
Normal file
|
@ -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
|
17
src/Network/OWSSignalService.h
Normal file
17
src/Network/OWSSignalService.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
// Created by Michael Kirk on 12/20/16.
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSStorageManager;
|
||||
@class TSAccountManager;
|
||||
@class AFHTTPSessionManager;
|
||||
|
||||
@interface OWSSignalService : NSObject
|
||||
|
||||
@property (nonatomic, readonly) BOOL isCensored;
|
||||
@property (nonatomic, readonly) AFHTTPSessionManager *HTTPSessionManager;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
138
src/Network/OWSSignalService.m
Normal file
138
src/Network/OWSSignalService.m
Normal file
|
@ -0,0 +1,138 @@
|
|||
// 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 <AFNetworking/AFHTTPSessionManager.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSSignalService ()
|
||||
|
||||
@property (nonatomic, readonly, strong) OWSCensorshipConfiguration *censorshipConfiguration;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSSignalService
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_censorshipConfiguration = [OWSCensorshipConfiguration new];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isCensored
|
||||
{
|
||||
NSString *localNumber = [TSAccountManager localNumber];
|
||||
|
||||
if (localNumber) {
|
||||
return [self.censorshipConfiguration isCensoredPhoneNumber:localNumber];
|
||||
} else {
|
||||
DDLogError(@"no known phone number to check for censorship.");
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (AFHTTPSessionManager *)HTTPSessionManager
|
||||
{
|
||||
if (self.isCensored) {
|
||||
DDLogInfo(@"%@ using reflector HTTPSessionManager", self.tag);
|
||||
return self.reflectorHTTPSessionManager;
|
||||
} else {
|
||||
DDLogDebug(@"%@ using default HTTPSessionManager", self.tag);
|
||||
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];
|
||||
|
||||
sessionManager.securityPolicy = [[self class] googlePinningPolicy];
|
||||
|
||||
sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
|
||||
[sessionManager.requestSerializer setValue:self.censorshipConfiguration.reflectorHost forHTTPHeaderField:@"Host"];
|
||||
|
||||
sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
|
||||
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
#pragma mark - Google Pinning Policy
|
||||
|
||||
/**
|
||||
* We use the Google Pinning Policy when connecting to our censorship circumventing reflector,
|
||||
* which is hosted on Google.
|
||||
*/
|
||||
+ (AFSecurityPolicy *)googlePinningPolicy {
|
||||
static AFSecurityPolicy *securityPolicy = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSError *error;
|
||||
NSString *path = [NSBundle.mainBundle pathForResource:@"GIAG2" ofType:@"crt"];
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
|
||||
@throw [NSException
|
||||
exceptionWithName:@"Missing server certificate"
|
||||
reason:[NSString stringWithFormat:@"Missing signing certificate for service googlePinningPolicy"]
|
||||
userInfo:nil];
|
||||
}
|
||||
|
||||
NSData *googleCertData = [NSData dataWithContentsOfFile:path options:0 error:&error];
|
||||
if (!googleCertData) {
|
||||
if (error) {
|
||||
@throw [NSException exceptionWithName:@"OWSSignalServiceHTTPSecurityPolicy" reason:@"Couln't read google pinning cert" userInfo:nil];
|
||||
} else {
|
||||
NSString *reason = [NSString stringWithFormat:@"Reading google pinning cert faile with error: %@", error];
|
||||
@throw [NSException exceptionWithName:@"OWSSignalServiceHTTPSecurityPolicy" reason:reason userInfo:nil];
|
||||
}
|
||||
}
|
||||
|
||||
NSSet<NSData *> *certificates = [NSSet setWithObject:googleCertData];
|
||||
securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:certificates];
|
||||
});
|
||||
return securityPolicy;
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
||||
+ (NSString *)tag
|
||||
{
|
||||
return [NSString stringWithFormat:@"[%@]", self.class];
|
||||
}
|
||||
|
||||
- (NSString *)tag
|
||||
{
|
||||
return self.class.tag;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -8,15 +8,15 @@
|
|||
|
||||
#import "SubProtocol.pb.h"
|
||||
|
||||
#import "Cryptography.h"
|
||||
#import "OWSSignalService.h"
|
||||
#import "OWSWebsocketSecurityPolicy.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSConstants.h"
|
||||
#import "TSMessagesManager.h"
|
||||
#import "TSSocketManager.h"
|
||||
#import "TSStorageManager+keyingMaterial.h"
|
||||
|
||||
#import "OWSWebsocketSecurityPolicy.h"
|
||||
#import "Cryptography.h"
|
||||
|
||||
#define kWebSocketHeartBeat 30
|
||||
#define kWebSocketReconnectTry 5
|
||||
#define kBackgroundConnectTimer 25
|
||||
|
@ -27,6 +27,9 @@ NSString *const SocketClosedNotification = @"SocketClosedNotification";
|
|||
NSString *const SocketConnectingNotification = @"SocketConnectingNotification";
|
||||
|
||||
@interface TSSocketManager ()
|
||||
|
||||
@property (nonatomic, readonly, strong) OWSSignalService *signalService;
|
||||
|
||||
@property (nonatomic, retain) NSTimer *pingTimer;
|
||||
@property (nonatomic, retain) NSTimer *reconnectTimer;
|
||||
|
||||
|
@ -47,14 +50,18 @@ NSString *const SocketConnectingNotification = @"SocketConnectingNotification";
|
|||
|
||||
@implementation TSSocketManager
|
||||
|
||||
- (instancetype)init {
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
self.websocket = nil;
|
||||
[self addObserver:self forKeyPath:@"status" options:0 context:kSocketStatusObservationContext];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_signalService = [OWSSignalService new];
|
||||
_websocket = nil;
|
||||
[self addObserver:self forKeyPath:@"status" options:0 context:kSocketStatusObservationContext];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -73,38 +80,46 @@ NSString *const SocketConnectingNotification = @"SocketConnectingNotification";
|
|||
|
||||
#pragma mark - Manage Socket
|
||||
|
||||
+ (void)becomeActive {
|
||||
TSSocketManager *sharedInstance = [self sharedManager];
|
||||
SRWebSocket *socket = [sharedInstance websocket];
|
||||
+ (void)becomeActive
|
||||
{
|
||||
[[self sharedManager] becomeActive];
|
||||
}
|
||||
|
||||
- (void)becomeActive
|
||||
{
|
||||
if (self.signalService.isCensored) {
|
||||
DDLogWarn(@"%@ Refusing to start websocket in `becomeActive`.", self.tag);
|
||||
return;
|
||||
}
|
||||
|
||||
SRWebSocket *socket = self.websocket;
|
||||
if (socket) {
|
||||
switch ([socket readyState]) {
|
||||
case SR_OPEN:
|
||||
DDLogVerbose(@"WebSocket already open on connection request");
|
||||
sharedInstance.status = kSocketStatusOpen;
|
||||
self.status = kSocketStatusOpen;
|
||||
return;
|
||||
case SR_CONNECTING:
|
||||
DDLogVerbose(@"WebSocket is already connecting");
|
||||
sharedInstance.status = kSocketStatusConnecting;
|
||||
self.status = kSocketStatusConnecting;
|
||||
return;
|
||||
default:
|
||||
[socket close];
|
||||
sharedInstance.status = kSocketStatusClosed;
|
||||
self.status = kSocketStatusClosed;
|
||||
socket.delegate = nil;
|
||||
socket = nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NSString *webSocketConnect =
|
||||
[textSecureWebSocketAPI stringByAppendingString:[[self sharedManager] webSocketAuthenticationString]];
|
||||
NSString *webSocketConnect = [textSecureWebSocketAPI stringByAppendingString:[self webSocketAuthenticationString]];
|
||||
NSURL *webSocketConnectURL = [NSURL URLWithString:webSocketConnect];
|
||||
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:webSocketConnectURL];
|
||||
|
||||
socket = [[SRWebSocket alloc] initWithURLRequest:request securityPolicy:[OWSWebsocketSecurityPolicy sharedPolicy]];
|
||||
socket.delegate = [self sharedManager];
|
||||
socket = [[SRWebSocket alloc] initWithURLRequest:request securityPolicy:[OWSWebsocketSecurityPolicy sharedPolicy]];
|
||||
socket.delegate = self;
|
||||
|
||||
[[self sharedManager] setWebsocket:socket];
|
||||
[self setWebsocket:socket];
|
||||
[socket open];
|
||||
}
|
||||
|
||||
|
@ -362,4 +377,16 @@ NSString *const SocketConnectingNotification = @"SocketConnectingNotification";
|
|||
[[self sharedManager] notifyStatusChange];
|
||||
}
|
||||
|
||||
#pragma mark - Logging
|
||||
|
||||
+ (NSString *)tag
|
||||
{
|
||||
return [NSString stringWithFormat:@"[%@]", self.class];
|
||||
}
|
||||
|
||||
- (NSString *)tag
|
||||
{
|
||||
return self.class.tag;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
BIN
src/Security/PinningCertificate/GIAG2.crt
Normal file
BIN
src/Security/PinningCertificate/GIAG2.crt
Normal file
Binary file not shown.
Loading…
Reference in a new issue