replace SocketRocket with Starscream
This commit is contained in:
parent
4b3c43eed6
commit
16c8a1a76e
9
Podfile
9
Podfile
|
@ -38,12 +38,6 @@ def shared_pods
|
|||
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master'
|
||||
# pod 'Mantle', path: '../Mantle'
|
||||
|
||||
# SocketRocket has some critical crash fixes on Github, but have published an official release to cocoapods in ages, so
|
||||
# we were following master
|
||||
# Forked and have an open PR with our changes, but they have not been merged.
|
||||
# pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git', inhibit_warnings: true
|
||||
pod 'SocketRocket', :git => 'https://github.com/signalapp/SocketRocket.git', branch: 'mkirk/handle-sec-err', inhibit_warnings: true
|
||||
|
||||
# Forked for compatibily with the ShareExtension, changes have an open PR, but have not been merged.
|
||||
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release'
|
||||
# pod 'YapDatabase/SQLCipher', path: '../YapDatabase'
|
||||
|
@ -52,6 +46,9 @@ def shared_pods
|
|||
pod 'GRKOpenSSLFramework', git: 'https://github.com/signalapp/GRKOpenSSLFramework'
|
||||
#pod 'GRKOpenSSLFramework', path: '../GRKOpenSSLFramework'
|
||||
|
||||
pod 'Starscream', git: 'git@github.com:signalapp/Starscream.git', branch: 'signal-release'
|
||||
# pod 'Starscream', path: '../Starscream'
|
||||
|
||||
###
|
||||
# third party pods
|
||||
####
|
||||
|
|
26
Podfile.lock
26
Podfile.lock
|
@ -94,7 +94,7 @@ PODS:
|
|||
- SAMKeychain
|
||||
- SignalCoreKit
|
||||
- SignalMetadataKit
|
||||
- SocketRocket
|
||||
- Starscream
|
||||
- SwiftProtobuf
|
||||
- YapDatabase/SQLCipher
|
||||
- SignalServiceKit/Tests (0.9.0):
|
||||
|
@ -110,16 +110,16 @@ PODS:
|
|||
- SAMKeychain
|
||||
- SignalCoreKit
|
||||
- SignalMetadataKit
|
||||
- SocketRocket
|
||||
- Starscream
|
||||
- SwiftProtobuf
|
||||
- YapDatabase/SQLCipher
|
||||
- SocketRocket (0.5.1)
|
||||
- SQLCipher (4.0.1):
|
||||
- SQLCipher/standard (= 4.0.1)
|
||||
- SQLCipher/common (4.0.1)
|
||||
- SQLCipher/standard (4.0.1):
|
||||
- SQLCipher/common
|
||||
- SSZipArchive (2.1.4)
|
||||
- Starscream (3.0.6)
|
||||
- SwiftProtobuf (1.2.0)
|
||||
- YapDatabase/SQLCipher (3.1.1):
|
||||
- YapDatabase/SQLCipher/Core (= 3.1.1)
|
||||
|
@ -205,9 +205,9 @@ DEPENDENCIES:
|
|||
- SignalMetadataKit/Tests (from `https://github.com/signalapp/SignalMetadataKit`)
|
||||
- SignalServiceKit (from `.`)
|
||||
- SignalServiceKit/Tests (from `.`)
|
||||
- SocketRocket (from `https://github.com/signalapp/SocketRocket.git`, branch `mkirk/handle-sec-err`)
|
||||
- SQLCipher (>= 4.0.1)
|
||||
- SSZipArchive
|
||||
- "Starscream (from `git@github.com:signalapp/Starscream.git`, branch `signal-release`)"
|
||||
- YapDatabase/SQLCipher (from `https://github.com/signalapp/YapDatabase.git`, branch `signal-release`)
|
||||
- YYImage
|
||||
|
||||
|
@ -244,9 +244,9 @@ EXTERNAL SOURCES:
|
|||
:git: https://github.com/signalapp/SignalMetadataKit
|
||||
SignalServiceKit:
|
||||
:path: "."
|
||||
SocketRocket:
|
||||
:branch: mkirk/handle-sec-err
|
||||
:git: https://github.com/signalapp/SocketRocket.git
|
||||
Starscream:
|
||||
:branch: signal-release
|
||||
:git: "git@github.com:signalapp/Starscream.git"
|
||||
YapDatabase:
|
||||
:branch: signal-release
|
||||
:git: https://github.com/signalapp/YapDatabase.git
|
||||
|
@ -273,9 +273,9 @@ CHECKOUT OPTIONS:
|
|||
SignalMetadataKit:
|
||||
:commit: 56f28fc3a6e35d548d034ef7d0009f233ca0aa62
|
||||
:git: https://github.com/signalapp/SignalMetadataKit
|
||||
SocketRocket:
|
||||
:commit: 9f9563a83cd8960503074aa8de72206f83fb7a69
|
||||
:git: https://github.com/signalapp/SocketRocket.git
|
||||
Starscream:
|
||||
:commit: edfb5964c5375ca55b3b0c517e1b5b7d0ac4519a
|
||||
:git: "git@github.com:signalapp/Starscream.git"
|
||||
YapDatabase:
|
||||
:commit: 8e2b69110efd9499a5b553fda0165d2cea4e818d
|
||||
:git: https://github.com/signalapp/YapDatabase.git
|
||||
|
@ -295,14 +295,14 @@ SPEC CHECKSUMS:
|
|||
SAMKeychain: 483e1c9f32984d50ca961e26818a534283b4cd5c
|
||||
SignalCoreKit: c2d8132cdedb95d35eb2f8ae7eac0957695d0a8b
|
||||
SignalMetadataKit: 6fa5e9a53c7f104568662521a2f3874672ff7a02
|
||||
SignalServiceKit: 80d774c32b22567682f63c36bf9da265d82083bb
|
||||
SocketRocket: dbb1554b8fc288ef8ef370d6285aeca7361be31e
|
||||
SignalServiceKit: c637b66e485538dda76836a1ec560dc556035430
|
||||
SQLCipher: 4636a257060f6f1b4e143a143028b61a2b462d0d
|
||||
SSZipArchive: 41455d4b8d2b6ab93990820b50dc697c2554a322
|
||||
Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5
|
||||
SwiftProtobuf: 91a9856079044ef4ec762b2344c763cd9e5a73c1
|
||||
YapDatabase: b418a4baa6906e8028748938f9159807fd039af4
|
||||
YYImage: 1e1b62a9997399593e4b9c4ecfbbabbf1d3f3b54
|
||||
|
||||
PODFILE CHECKSUM: 7ccd091c65f353c7fcc3021a13b557a576d48509
|
||||
PODFILE CHECKSUM: 7856bf087f931a4089ebd9a08ed1dfe8389b8afc
|
||||
|
||||
COCOAPODS: 1.5.3
|
||||
|
|
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 527dca96c23f0ac15664e9762987ff017cabdf90
|
||||
Subproject commit c653092655ec0c592d7e733e1bd5eee342849ae0
|
|
@ -3145,7 +3145,7 @@
|
|||
"${BUILT_PRODUCTS_DIR}/SignalCoreKit/SignalCoreKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SignalMetadataKit/SignalMetadataKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SignalServiceKit/SignalServiceKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SocketRocket/SocketRocket.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
|
||||
|
@ -3169,7 +3169,7 @@
|
|||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalCoreKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalMetadataKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalServiceKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SocketRocket.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
|
||||
|
@ -3220,7 +3220,7 @@
|
|||
"${BUILT_PRODUCTS_DIR}/SignalCoreKit/SignalCoreKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SignalMetadataKit/SignalMetadataKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SignalServiceKit/SignalServiceKit.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SocketRocket/SocketRocket.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/YapDatabase/YapDatabase.framework",
|
||||
|
@ -3243,7 +3243,7 @@
|
|||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalCoreKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalMetadataKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SignalServiceKit.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SocketRocket.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YapDatabase.framework",
|
||||
|
|
|
@ -44,7 +44,7 @@ An Objective-C library for communicating with the Signal messaging service.
|
|||
s.dependency 'AxolotlKit'
|
||||
s.dependency 'Mantle'
|
||||
s.dependency 'YapDatabase/SQLCipher'
|
||||
s.dependency 'SocketRocket'
|
||||
s.dependency 'Starscream'
|
||||
s.dependency 'libPhoneNumber-iOS'
|
||||
s.dependency 'GRKOpenSSLFramework'
|
||||
s.dependency 'SAMKeychain'
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
//
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Starscream
|
||||
|
||||
@objc
|
||||
public enum SSKWebSocketState: UInt {
|
||||
case open, connecting, disconnected
|
||||
}
|
||||
|
||||
@objc
|
||||
public class SSKWebSocketError: NSObject, CustomNSError {
|
||||
|
||||
init(underlyingError: Starscream.WSError) {
|
||||
self.underlyingError = underlyingError
|
||||
}
|
||||
|
||||
// MARK: - CustomNSError
|
||||
|
||||
@objc
|
||||
public static let errorDomain = "SignalServiceKit.SSKWebSocketError"
|
||||
|
||||
public var errorUserInfo: [String: Any] {
|
||||
return [
|
||||
type(of: self).kStatusCodeKey: underlyingError.code,
|
||||
NSUnderlyingErrorKey: (underlyingError as NSError)
|
||||
]
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@objc
|
||||
static let kStatusCodeKey = "SSKWebSocketErrorStatusCode"
|
||||
|
||||
let underlyingError: Starscream.WSError
|
||||
}
|
||||
|
||||
@objc
|
||||
public protocol SSKWebSocket {
|
||||
|
||||
@objc
|
||||
var delegate: SSKWebSocketDelegate? { get set }
|
||||
|
||||
@objc
|
||||
var state: SSKWebSocketState { get }
|
||||
|
||||
@objc
|
||||
func connect()
|
||||
|
||||
@objc
|
||||
func disconnect()
|
||||
|
||||
@objc(writeData:error:)
|
||||
func write(data: Data) throws
|
||||
|
||||
@objc
|
||||
func writePing() throws
|
||||
}
|
||||
|
||||
@objc
|
||||
public protocol SSKWebSocketDelegate: class {
|
||||
func websocketDidConnect(socket: SSKWebSocket)
|
||||
|
||||
func websocketDidDisconnect(socket: SSKWebSocket, error: Error?)
|
||||
|
||||
func websocketDidReceiveData(socket: SSKWebSocket, data: Data)
|
||||
|
||||
@objc optional func websocketDidReceiveMessage(socket: SSKWebSocket, text: String)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class SSKWebSocketManager: NSObject {
|
||||
|
||||
@objc
|
||||
public class func buildSocket(request: URLRequest) -> SSKWebSocket {
|
||||
return SSKWebSocketImpl(request: request)
|
||||
}
|
||||
}
|
||||
|
||||
class SSKWebSocketImpl: SSKWebSocket {
|
||||
|
||||
private let socket: Starscream.WebSocket
|
||||
|
||||
init(request: URLRequest) {
|
||||
let socket = WebSocket(request: request)
|
||||
|
||||
socket.disableSSLCertValidation = true
|
||||
socket.socketSecurityLevel = StreamSocketSecurityLevel.tlSv1_2
|
||||
let security = SSLSecurity(certs: [TextSecureCertificate()], usePublicKeys: false)
|
||||
security.validateEntireChain = false
|
||||
socket.security = security
|
||||
|
||||
// TODO cipher suite selection
|
||||
// socket.enabledSSLCipherSuites = [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
|
||||
|
||||
self.socket = socket
|
||||
|
||||
socket.delegate = self
|
||||
}
|
||||
|
||||
// MARK: - SSKWebSocket
|
||||
|
||||
weak var delegate: SSKWebSocketDelegate?
|
||||
|
||||
var hasEverConnected = false
|
||||
var state: SSKWebSocketState {
|
||||
if socket.isConnected {
|
||||
return .open
|
||||
}
|
||||
|
||||
if hasEverConnected {
|
||||
return .disconnected
|
||||
}
|
||||
|
||||
return .connecting
|
||||
}
|
||||
|
||||
func connect() {
|
||||
socket.connect()
|
||||
}
|
||||
|
||||
func disconnect() {
|
||||
socket.disconnect()
|
||||
}
|
||||
|
||||
func write(data: Data) throws {
|
||||
socket.write(data: data)
|
||||
}
|
||||
|
||||
func writePing() throws {
|
||||
socket.write(ping: Data())
|
||||
}
|
||||
}
|
||||
|
||||
extension SSKWebSocketImpl: WebSocketDelegate {
|
||||
func websocketDidConnect(socket: WebSocketClient) {
|
||||
hasEverConnected = true
|
||||
delegate?.websocketDidConnect(socket: self)
|
||||
}
|
||||
|
||||
func websocketDidDisconnect(socket: WebSocketClient, error: Error?) {
|
||||
let websocketError: Error?
|
||||
switch error {
|
||||
case let wsError as WSError:
|
||||
websocketError = SSKWebSocketError(underlyingError: wsError)
|
||||
default:
|
||||
assert(error == nil, "unexpected error type: \(String(describing: error))")
|
||||
websocketError = error
|
||||
}
|
||||
|
||||
delegate?.websocketDidDisconnect(socket: self, error: websocketError)
|
||||
}
|
||||
|
||||
func websocketDidReceiveMessage(socket: WebSocketClient, text: String) {
|
||||
if let websocketDidReceiveMessage = self.delegate?.websocketDidReceiveMessage {
|
||||
websocketDidReceiveMessage(self, text)
|
||||
}
|
||||
}
|
||||
|
||||
func websocketDidReceiveData(socket: WebSocketClient, data: Data) {
|
||||
delegate?.websocketDidReceiveData(socket: self, data: data)
|
||||
}
|
||||
}
|
||||
|
||||
private func TextSecureCertificate() -> SSLCert {
|
||||
let data = OWSHTTPSecurityPolicy.dataFromCertificateFile(forService: "textsecure")
|
||||
return SSLCert(data: data)
|
||||
}
|
||||
|
||||
private extension StreamSocketSecurityLevel {
|
||||
static var tlSv1_2: StreamSocketSecurityLevel {
|
||||
return StreamSocketSecurityLevel(rawValue: "kCFStreamSocketSecurityLevelTLSv1_2")
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@
|
|||
#import "OWSMessageReceiver.h"
|
||||
#import "OWSPrimaryStorage.h"
|
||||
#import "OWSSignalService.h"
|
||||
#import "OWSWebsocketSecurityPolicy.h"
|
||||
#import "SSKEnvironment.h"
|
||||
#import "TSAccountManager.h"
|
||||
#import "TSConstants.h"
|
||||
|
@ -24,7 +23,6 @@
|
|||
#import <SignalCoreKit/Cryptography.h>
|
||||
#import <SignalCoreKit/Threading.h>
|
||||
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
||||
#import <SocketRocket/SRWebSocket.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
@ -144,13 +142,13 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
#pragma mark -
|
||||
|
||||
// OWSWebSocket's properties should only be accessed from the main thread.
|
||||
@interface OWSWebSocket () <SRWebSocketDelegate>
|
||||
@interface OWSWebSocket () <SSKWebSocketDelegate>
|
||||
|
||||
// This class has a few "tiers" of state.
|
||||
//
|
||||
// The first tier is the actual websocket and the timers used
|
||||
// to keep it alive and connected.
|
||||
@property (nonatomic, nullable) SRWebSocket *websocket;
|
||||
@property (nonatomic, nullable) id<SSKWebSocket> websocket;
|
||||
@property (nonatomic, nullable) NSTimer *heartbeatTimer;
|
||||
@property (nonatomic, nullable) NSTimer *reconnectTimer;
|
||||
|
||||
|
@ -257,11 +255,6 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
return SSKEnvironment.shared.notificationsManager;
|
||||
}
|
||||
|
||||
- (OWSWebsocketSecurityPolicy *)websocketSecurityPolicy
|
||||
{
|
||||
return OWSWebsocketSecurityPolicy.sharedPolicy;
|
||||
}
|
||||
|
||||
- (id<OWSUDManager>)udManager {
|
||||
return SSKEnvironment.shared.udManager;
|
||||
}
|
||||
|
@ -310,11 +303,11 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
|
||||
// Try to reuse the existing socket (if any) if it is in a valid state.
|
||||
if (self.websocket) {
|
||||
switch ([self.websocket readyState]) {
|
||||
case SR_OPEN:
|
||||
switch (self.websocket.state) {
|
||||
case SSKWebSocketStateOpen:
|
||||
self.state = OWSWebSocketStateOpen;
|
||||
return;
|
||||
case SR_CONNECTING:
|
||||
case SSKWebSocketStateConnecting:
|
||||
OWSLogVerbose(@"WebSocket is already connecting");
|
||||
self.state = OWSWebSocketStateConnecting;
|
||||
return;
|
||||
|
@ -355,8 +348,7 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
// and class state to reflect changes in app state.
|
||||
//
|
||||
// We learn about changes to socket state through websocket
|
||||
// delegate methods like [webSocketDidOpen:], [didFailWithError:...]
|
||||
// and [didCloseWithCode:...]. These delegate methods are sometimes
|
||||
// delegate methods. These delegate methods are sometimes
|
||||
// invoked _after_ web socket state changes, so we sometimes learn
|
||||
// about changes to socket state in [ensureWebsocket]. Put another way,
|
||||
// it's not safe to assume we'll learn of changes to websocket state
|
||||
|
@ -425,18 +417,17 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
NSURL *webSocketConnectURL = [NSURL URLWithString:webSocketConnect];
|
||||
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:webSocketConnectURL];
|
||||
|
||||
SRWebSocket *socket =
|
||||
[[SRWebSocket alloc] initWithURLRequest:request securityPolicy:self.websocketSecurityPolicy];
|
||||
id<SSKWebSocket> socket = [SSKWebSocketManager buildSocketWithRequest:request];
|
||||
socket.delegate = self;
|
||||
|
||||
[self setWebsocket:socket];
|
||||
|
||||
// [SRWebSocket open] could hypothetically call a delegate method (e.g. if
|
||||
// `connect` could hypothetically call a delegate method (e.g. if
|
||||
// the socket failed immediately for some reason), so we update the state
|
||||
// _before_ calling it, not after.
|
||||
_state = state;
|
||||
self.canMakeRequests = state == OWSWebSocketStateOpen;
|
||||
[socket open];
|
||||
[socket connect];
|
||||
[self failAllPendingSocketMessagesIfNecessary];
|
||||
return;
|
||||
}
|
||||
|
@ -463,7 +454,7 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
OWSAssertIsOnMainThread();
|
||||
|
||||
self.websocket.delegate = nil;
|
||||
[self.websocket close];
|
||||
[self.websocket disconnect];
|
||||
self.websocket = nil;
|
||||
[self.heartbeatTimer invalidate];
|
||||
self.heartbeatTimer = nil;
|
||||
|
@ -554,7 +545,7 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
return;
|
||||
}
|
||||
|
||||
BOOL wasScheduled = [self.websocket sendDataNoCopy:messageData error:&error];
|
||||
BOOL wasScheduled = [self.websocket writeData:messageData error:&error];
|
||||
if (!wasScheduled || error) {
|
||||
OWSFailDebug(@"could not send socket request: %@", error);
|
||||
[socketMessage didFailBeforeSending];
|
||||
|
@ -676,13 +667,13 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark - Delegate methods
|
||||
#pragma mark - SSKWebSocketDelegate
|
||||
|
||||
- (void)webSocketDidOpen:(SRWebSocket *)webSocket
|
||||
- (void)websocketDidConnectWithSocket:(id<SSKWebSocket>)websocket
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssertDebug(webSocket);
|
||||
if (webSocket != self.websocket) {
|
||||
OWSAssertDebug(websocket);
|
||||
if (websocket != self.websocket) {
|
||||
// Ignore events from obsolete web sockets.
|
||||
return;
|
||||
}
|
||||
|
@ -695,19 +686,18 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
[self.outageDetection reportConnectionSuccess];
|
||||
}
|
||||
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error
|
||||
- (void)websocketDidDisconnectWithSocket:(id<SSKWebSocket>)websocket error:(nullable NSError *)error
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssertDebug(webSocket);
|
||||
if (webSocket != self.websocket) {
|
||||
OWSAssertDebug(websocket);
|
||||
if (websocket != self.websocket) {
|
||||
// Ignore events from obsolete web sockets.
|
||||
return;
|
||||
}
|
||||
|
||||
OWSLogError(@"Websocket did fail with error: %@", error);
|
||||
|
||||
if ([error.domain isEqualToString:SRWebSocketErrorDomain] && error.code == 2132) {
|
||||
NSNumber *_Nullable statusCode = error.userInfo[SRHTTPResponseErrorKey];
|
||||
if ([error.domain isEqualToString:SSKWebSocketError.errorDomain]) {
|
||||
NSNumber *_Nullable statusCode = error.userInfo[SSKWebSocketError.kStatusCodeKey];
|
||||
if (statusCode.unsignedIntegerValue == 403) {
|
||||
if (self.tsAccountManager.isRegisteredAndReady) {
|
||||
[self.tsAccountManager setIsDeregistered:YES];
|
||||
|
@ -720,12 +710,12 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
[self handleSocketFailure];
|
||||
}
|
||||
|
||||
- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(NSData *)data
|
||||
- (void)websocketDidReceiveDataWithSocket:(id<SSKWebSocket>)websocket data:(NSData *)data
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssertDebug(webSocket);
|
||||
OWSAssertDebug(websocket);
|
||||
|
||||
if (webSocket != self.websocket) {
|
||||
if (websocket != self.websocket) {
|
||||
// Ignore events from obsolete web sockets.
|
||||
return;
|
||||
}
|
||||
|
@ -749,6 +739,8 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (dispatch_queue_t)serialQueue
|
||||
{
|
||||
static dispatch_queue_t _serialQueue;
|
||||
|
@ -853,7 +845,7 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
return;
|
||||
}
|
||||
|
||||
[self.websocket sendDataNoCopy:messageData error:&error];
|
||||
[self.websocket writeData:messageData error:&error];
|
||||
if (error) {
|
||||
OWSLogWarn(@"Error while trying to write on websocket %@", error);
|
||||
[self handleSocketFailure];
|
||||
|
@ -887,30 +879,13 @@ NSString *const kNSNotification_OWSWebSocketStateDidChange = @"kNSNotification_O
|
|||
[self.outageDetection reportConnectionFailure];
|
||||
}
|
||||
|
||||
- (void)webSocket:(SRWebSocket *)webSocket
|
||||
didCloseWithCode:(NSInteger)code
|
||||
reason:(nullable NSString *)reason
|
||||
wasClean:(BOOL)wasClean
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
OWSAssertDebug(webSocket);
|
||||
if (webSocket != self.websocket) {
|
||||
// Ignore events from obsolete web sockets.
|
||||
return;
|
||||
}
|
||||
|
||||
OWSLogWarn(@"Websocket did close with code: %ld", (long)code);
|
||||
|
||||
[self handleSocketFailure];
|
||||
}
|
||||
|
||||
- (void)webSocketHeartBeat
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
if ([self shouldSocketBeOpen]) {
|
||||
NSError *error;
|
||||
[self.websocket sendPing:nil error:&error];
|
||||
[self.websocket writePingAndReturnError:&error];
|
||||
if (error) {
|
||||
OWSLogWarn(@"Error in websocket heartbeat: %@", error.localizedDescription);
|
||||
[self handleSocketFailure];
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
//
|
||||
// Created by Fred on 01/09/15.
|
||||
// Copyright © 2015 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <AFNetworking/AFSecurityPolicy.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSData *SSKTextSecureServiceCertificateData(void);
|
||||
|
||||
@interface OWSHTTPSecurityPolicy : AFSecurityPolicy
|
||||
|
||||
+ (instancetype)sharedPolicy;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSHTTPSecurityPolicy.h"
|
||||
#import <AssertMacros.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation OWSHTTPSecurityPolicy
|
||||
|
||||
+ (instancetype)sharedPolicy {
|
||||
|
@ -21,24 +23,15 @@
|
|||
|
||||
if (self) {
|
||||
self.pinnedCertificates = [NSSet setWithArray:@[
|
||||
[self certificateDataForService:@"textsecure"],
|
||||
[self.class certificateDataForService:@"textsecure"]
|
||||
]];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray *)certs {
|
||||
return @[ (__bridge id)[self certificateForService:@"textsecure"] ];
|
||||
}
|
||||
|
||||
- (NSData *)certificateDataForService:(NSString *)service {
|
||||
SecCertificateRef certRef = [self certificateForService:service];
|
||||
return (__bridge_transfer NSData *)SecCertificateCopyData(certRef);
|
||||
}
|
||||
|
||||
- (SecCertificateRef)certificateForService:(NSString *)service {
|
||||
|
||||
+ (NSData *)dataFromCertificateFileForService:(NSString *)service
|
||||
{
|
||||
NSBundle *bundle = [NSBundle bundleForClass:self.class];
|
||||
NSString *path = [bundle pathForResource:service ofType:@"cer"];
|
||||
|
||||
|
@ -46,12 +39,25 @@
|
|||
OWSFail(@"Missing signing certificate for service %@", service);
|
||||
}
|
||||
|
||||
NSData *certificateData = [NSData dataWithContentsOfFile:path];
|
||||
NSData *data = [NSData dataWithContentsOfFile:path];
|
||||
OWSAssert(data.length > 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
+ (NSData *)certificateDataForService:(NSString *)service {
|
||||
SecCertificateRef certRef = [self certificateForService:service];
|
||||
return (__bridge_transfer NSData *)SecCertificateCopyData(certRef);
|
||||
}
|
||||
|
||||
+ (SecCertificateRef)certificateForService:(NSString *)service
|
||||
{
|
||||
NSData *certificateData = [self dataFromCertificateFileForService:service];
|
||||
return SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(certificateData));
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain {
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(nullable NSString *)domain
|
||||
{
|
||||
NSMutableArray *policies = [NSMutableArray array];
|
||||
[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
|
||||
|
||||
|
@ -90,3 +96,5 @@ _out:
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import <SocketRocket/SRSecurityPolicy.h>
|
||||
|
||||
@interface OWSWebsocketSecurityPolicy : SRSecurityPolicy
|
||||
|
||||
+ (instancetype)sharedPolicy;
|
||||
|
||||
@end
|
|
@ -1,29 +0,0 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSWebsocketSecurityPolicy.h"
|
||||
#import "OWSHTTPSecurityPolicy.h"
|
||||
#import <SocketRocket/SRSecurityPolicy.h>
|
||||
|
||||
@implementation OWSWebsocketSecurityPolicy
|
||||
|
||||
+ (instancetype)sharedPolicy {
|
||||
static OWSWebsocketSecurityPolicy *websocketSecurityPolicy = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
// We use our own CA
|
||||
websocketSecurityPolicy = [[self alloc] initWithCertificateChainValidationEnabled:NO];
|
||||
#pragma clang diagnostic pop
|
||||
});
|
||||
return websocketSecurityPolicy;
|
||||
}
|
||||
|
||||
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain {
|
||||
// Delegate server trust to our existing HTTP policy.
|
||||
return [[OWSHTTPSecurityPolicy sharedPolicy] evaluateServerTrust:serverTrust forDomain:domain];
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue