mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-04 10:30:42 +00:00
Merge branch 'modern-networking'
This commit is contained in:
commit
ec8519c25e
@ -3,10 +3,10 @@ load("//Config:buck_rule_macros.bzl", "static_library", "framework", "glob_map",
|
||||
framework(
|
||||
name = "MtProtoKit",
|
||||
srcs = glob([
|
||||
"Sources/*.m",
|
||||
"Sources/**/*.m",
|
||||
]),
|
||||
headers = glob([
|
||||
"Sources/*.h",
|
||||
"Sources/**/*.h",
|
||||
]),
|
||||
exported_headers = glob([
|
||||
"PublicHeaders/**/*.h",
|
||||
|
@ -4,8 +4,8 @@ objc_library(
|
||||
enable_modules = True,
|
||||
module_name = "MtProtoKit",
|
||||
srcs = glob([
|
||||
"Sources/*.m",
|
||||
"Sources/*.h",
|
||||
"Sources/**/*.m",
|
||||
"Sources/**/*.h",
|
||||
]),
|
||||
hdrs = glob([
|
||||
"PublicHeaders/**/*.h",
|
||||
|
@ -0,0 +1,9 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MtProtoKit/MTMessageService.h>
|
||||
#import <MtProtoKit/MTDatacenterAuthInfo.h>
|
||||
|
||||
@interface MTBindKeyMessageService : NSObject <MTMessageService>
|
||||
|
||||
- (instancetype)initWithPersistentKey:(MTDatacenterAuthKey *)persistentKey ephemeralKey:(MTDatacenterAuthKey *)ephemeralKey completion:(void (^)(bool))completion;
|
||||
|
||||
@end
|
@ -20,7 +20,7 @@
|
||||
@optional
|
||||
|
||||
- (void)contextDatacenterAddressSetUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId addressSet:(MTDatacenterAddressSet *)addressSet;
|
||||
- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo;
|
||||
- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector;
|
||||
- (void)contextDatacenterAuthTokenUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authToken:(id)authToken;
|
||||
- (void)contextDatacenterTransportSchemesUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId shouldReset:(bool)shouldReset;
|
||||
- (void)contextIsPasswordRequiredUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId;
|
||||
@ -49,6 +49,7 @@
|
||||
@property (nonatomic, strong, readonly) MTApiEnvironment *apiEnvironment;
|
||||
@property (nonatomic, readonly) bool isTestingEnvironment;
|
||||
@property (nonatomic, readonly) bool useTempAuthKeys;
|
||||
@property (nonatomic, readonly) int32_t tempKeyExpiration;
|
||||
|
||||
+ (int32_t)fixedTimeDifference;
|
||||
+ (void)setFixedTimeDifference:(int32_t)fixedTimeDifference;
|
||||
@ -73,7 +74,7 @@
|
||||
- (void)updateAddressSetForDatacenterWithId:(NSInteger)datacenterId addressSet:(MTDatacenterAddressSet *)addressSet forceUpdateSchemes:(bool)forceUpdateSchemes;
|
||||
- (void)addAddressForDatacenterWithId:(NSInteger)datacenterId address:(MTDatacenterAddress *)address;
|
||||
- (void)updateTransportSchemeForDatacenterWithId:(NSInteger)datacenterId transportScheme:(MTTransportScheme *)transportScheme media:(bool)media isProxy:(bool)isProxy;
|
||||
- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo;
|
||||
- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector;
|
||||
|
||||
- (bool)isPasswordInputRequiredForDatacenterWithId:(NSInteger)datacenterId;
|
||||
- (bool)updatePasswordInputRequiredForDatacenterWithId:(NSInteger)datacenterId required:(bool)required;
|
||||
@ -95,7 +96,7 @@
|
||||
- (void)transportSchemeForDatacenterWithIdRequired:(NSInteger)datacenterId media:(bool)media;
|
||||
- (void)invalidateTransportSchemeForDatacenterId:(NSInteger)datacenterId transportScheme:(MTTransportScheme *)transportScheme isProbablyHttp:(bool)isProbablyHttp media:(bool)media;
|
||||
- (void)revalidateTransportSchemeForDatacenterId:(NSInteger)datacenterId transportScheme:(MTTransportScheme *)transportScheme media:(bool)media;
|
||||
- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId;
|
||||
- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId selector:(MTDatacenterAuthInfoSelector)selector;
|
||||
|
||||
- (NSArray<NSDictionary *> *)publicKeysForDatacenterWithId:(NSInteger)datacenterId;
|
||||
- (void)updatePublicKeysForDatacenterWithId:(NSInteger)datacenterId publicKeys:(NSArray<NSDictionary *> *)publicKeys;
|
||||
@ -107,8 +108,7 @@
|
||||
- (void)updateAuthTokenForDatacenterWithId:(NSInteger)datacenterId authToken:(id)authToken;
|
||||
|
||||
- (void)addressSetForDatacenterWithIdRequired:(NSInteger)datacenterId;
|
||||
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn;
|
||||
- (void)tempAuthKeyForDatacenterWithIdRequired:(NSInteger)datacenterId keyType:(MTDatacenterAuthTempKeyType)keyType;
|
||||
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector;
|
||||
- (void)authTokenForDatacenterWithIdRequired:(NSInteger)datacenterId authToken:(id)authToken masterDatacenterId:(NSInteger)masterDatacenterId;
|
||||
|
||||
- (void)reportProblemsWithDatacenterAddressForId:(NSInteger)datacenterId address:(MTDatacenterAddress *)address;
|
||||
|
@ -4,23 +4,12 @@
|
||||
|
||||
|
||||
@class MTContext;
|
||||
@class MTDatacenterAuthAction;
|
||||
|
||||
@protocol MTDatacenterAuthActionDelegate <NSObject>
|
||||
|
||||
- (void)datacenterAuthActionCompleted:(MTDatacenterAuthAction *)action;
|
||||
|
||||
@end
|
||||
|
||||
@interface MTDatacenterAuthAction : NSObject
|
||||
|
||||
@property (nonatomic, readonly) bool tempAuth;
|
||||
@property (nonatomic, weak) id<MTDatacenterAuthActionDelegate> delegate;
|
||||
@property (nonatomic, copy) void (^completedWithResult)(bool);
|
||||
- (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn completion:(void (^)(MTDatacenterAuthAction *, bool))completion;
|
||||
|
||||
- (instancetype)initWithTempAuth:(bool)tempAuth tempAuthKeyType:(MTDatacenterAuthTempKeyType)tempAuthKeyType bindKey:(MTDatacenterAuthKey *)bindKey;
|
||||
|
||||
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId isCdn:(bool)isCdn;
|
||||
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId;
|
||||
- (void)cancel;
|
||||
|
||||
@end
|
||||
|
@ -1,10 +1,5 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MTDatacenterAuthTempKeyType) {
|
||||
MTDatacenterAuthTempKeyTypeMain,
|
||||
MTDatacenterAuthTempKeyTypeMedia
|
||||
};
|
||||
|
||||
@interface MTDatacenterAuthKey: NSObject <NSCoding>
|
||||
|
||||
@property (nonatomic, strong, readonly) NSData *authKey;
|
||||
@ -15,24 +10,24 @@ typedef NS_ENUM(NSUInteger, MTDatacenterAuthTempKeyType) {
|
||||
|
||||
@end
|
||||
|
||||
typedef NS_ENUM(int64_t, MTDatacenterAuthInfoSelector) {
|
||||
MTDatacenterAuthInfoSelectorPersistent = 0,
|
||||
MTDatacenterAuthInfoSelectorEphemeralMain,
|
||||
MTDatacenterAuthInfoSelectorEphemeralMedia
|
||||
};
|
||||
|
||||
@interface MTDatacenterAuthInfo : NSObject <NSCoding>
|
||||
|
||||
@property (nonatomic, strong, readonly) NSData *authKey;
|
||||
@property (nonatomic, readonly) int64_t authKeyId;
|
||||
@property (nonatomic, strong, readonly) NSArray *saltSet;
|
||||
@property (nonatomic, strong, readonly) NSDictionary *authKeyAttributes;
|
||||
@property (nonatomic, strong, readonly) MTDatacenterAuthKey *mainTempAuthKey;
|
||||
@property (nonatomic, strong, readonly) MTDatacenterAuthKey *mediaTempAuthKey;
|
||||
|
||||
@property (nonatomic, strong, readonly) MTDatacenterAuthKey *persistentAuthKey;
|
||||
|
||||
- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes mainTempAuthKey:(MTDatacenterAuthKey *)mainTempAuthKey mediaTempAuthKey:(MTDatacenterAuthKey *)mediaTempAuthKey;
|
||||
- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes;
|
||||
|
||||
- (int64_t)authSaltForMessageId:(int64_t)messageId;
|
||||
- (MTDatacenterAuthInfo *)mergeSaltSet:(NSArray *)updatedSaltSet forTimestamp:(NSTimeInterval)timestamp;
|
||||
|
||||
- (MTDatacenterAuthInfo *)withUpdatedAuthKeyAttributes:(NSDictionary *)authKeyAttributes;
|
||||
- (MTDatacenterAuthKey *)tempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type;
|
||||
- (MTDatacenterAuthInfo *)withUpdatedTempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type key:(MTDatacenterAuthKey *)key;
|
||||
|
||||
@end
|
||||
|
@ -1,11 +1,13 @@
|
||||
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MtProtoKit/MTDatacenterAuthInfo.h>
|
||||
|
||||
@class MTProto;
|
||||
@class MTIncomingMessage;
|
||||
@class MTMessageTransaction;
|
||||
@class MTApiEnvironment;
|
||||
@class MTSessionInfo;
|
||||
|
||||
@protocol MTMessageService <NSObject>
|
||||
|
||||
@ -15,10 +17,10 @@
|
||||
- (void)mtProtoDidAddService:(MTProto *)mtProto;
|
||||
- (void)mtProtoDidRemoveService:(MTProto *)mtProto;
|
||||
- (void)mtProtoPublicKeysUpdated:(MTProto *)mtProto datacenterId:(NSInteger)datacenterId publicKeys:(NSArray<NSDictionary *> *)publicKeys;
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto;
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo;
|
||||
- (void)mtProtoDidChangeSession:(MTProto *)mtProto;
|
||||
- (void)mtProtoServerDidChangeSession:(MTProto *)mtProto firstValidMessageId:(int64_t)firstValidMessageId otherValidMessageIds:(NSArray *)otherValidMessageIds;
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message;
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector;
|
||||
- (void)mtProto:(MTProto *)mtProto receivedQuickAck:(int32_t)quickAckId;
|
||||
- (void)mtProto:(MTProto *)mtProto transactionsMayHaveFailed:(NSArray *)transactionIds;
|
||||
- (void)mtProtoAllTransactionsMayHaveFailed:(MTProto *)mtProto;
|
||||
|
@ -71,4 +71,6 @@
|
||||
|
||||
- (void)_messageResendRequestFailed:(int64_t)messageId;
|
||||
|
||||
+ (NSData *)_manuallyEncryptedMessage:(NSData *)preparedData messageId:(int64_t)messageId authKey:(MTDatacenterAuthKey *)authKey;
|
||||
|
||||
@end
|
||||
|
@ -0,0 +1,13 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MtProtoKit/MTProtoPersistenceInterface.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MTProtoEngine : NSObject
|
||||
|
||||
- (instancetype)initWithPersistenceInterface:(id<MTProtoPersistenceInterface>)persistenceInterface;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@ -0,0 +1,12 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MtProtoKit/MTProtoEngine.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MTProtoInstance : NSObject
|
||||
|
||||
- (instancetype)initWithEngine:(MTProtoEngine *)engine;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,14 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class MTSignal;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol MTProtoPersistenceInterface <NSObject>
|
||||
|
||||
- (MTSignal *)get:(NSData *)key;
|
||||
- (void)set:(NSData *)key value:(NSData *)value;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
156
submodules/MtProtoKit/Sources/MTBindKeyMessageService.m
Normal file
156
submodules/MtProtoKit/Sources/MTBindKeyMessageService.m
Normal file
@ -0,0 +1,156 @@
|
||||
#import <MtProtoKit/MTBindKeyMessageService.h>
|
||||
|
||||
#import <MtProtoKit/MTTime.h>
|
||||
#import <MtProtoKit/MTContext.h>
|
||||
#import <MtProtoKit/MTProto.h>
|
||||
#import <MtProtoKit/MTSerialization.h>
|
||||
#import <MtProtoKit/MTOutgoingMessage.h>
|
||||
#import <MtProtoKit/MTIncomingMessage.h>
|
||||
#import <MtProtoKit/MTPreparedMessage.h>
|
||||
#import <MtProtoKit/MTMessageTransaction.h>
|
||||
#import <MtProtoKit/MTDatacenterSaltInfo.h>
|
||||
#import <MtProtoKit/MTSessionInfo.h>
|
||||
#import "MTInternalMessageParser.h"
|
||||
#import "MTRpcResultMessage.h"
|
||||
#import "MTBuffer.h"
|
||||
|
||||
@interface MTBindKeyMessageService () {
|
||||
MTDatacenterAuthKey *_persistentKey;
|
||||
MTDatacenterAuthKey *_ephemeralKey;
|
||||
void (^_completion)(bool);
|
||||
|
||||
int64_t _currentMessageId;
|
||||
id _currentTransactionId;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTBindKeyMessageService
|
||||
|
||||
- (instancetype)initWithPersistentKey:(MTDatacenterAuthKey *)persistentKey ephemeralKey:(MTDatacenterAuthKey *)ephemeralKey completion:(void (^)(bool))completion {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_persistentKey = persistentKey;
|
||||
_ephemeralKey = ephemeralKey;
|
||||
_completion = [completion copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)mtProtoDidAddService:(MTProto *)mtProto
|
||||
{
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
|
||||
{
|
||||
if (_currentTransactionId != nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
int64_t bindingMessageId = [sessionInfo generateClientMessageId:NULL];
|
||||
int32_t bindingSeqNo = [sessionInfo takeSeqNo:true];
|
||||
|
||||
int32_t expiresAt = (int32_t)([mtProto.context globalTime] + mtProto.context.tempKeyExpiration);
|
||||
|
||||
int64_t randomId = 0;
|
||||
arc4random_buf(&randomId, 8);
|
||||
|
||||
int64_t nonce = 0;
|
||||
arc4random_buf(&nonce, 8);
|
||||
|
||||
MTBuffer *decryptedMessage = [[MTBuffer alloc] init];
|
||||
//bind_auth_key_inner#75a3f765 nonce:long temp_auth_key_id:long perm_auth_key_id:long temp_session_id:long expires_at:int = BindAuthKeyInner;
|
||||
[decryptedMessage appendInt32:(int32_t)0x75a3f765];
|
||||
[decryptedMessage appendInt64:nonce];
|
||||
[decryptedMessage appendInt64:_ephemeralKey.authKeyId];
|
||||
[decryptedMessage appendInt64:_persistentKey.authKeyId];
|
||||
[decryptedMessage appendInt64:sessionInfo.sessionId];
|
||||
[decryptedMessage appendInt32:expiresAt];
|
||||
|
||||
NSData *encryptedMessage = [MTProto _manuallyEncryptedMessage:[decryptedMessage data] messageId:bindingMessageId authKey:_persistentKey];
|
||||
|
||||
MTBuffer *bindRequestData = [[MTBuffer alloc] init];
|
||||
|
||||
//auth.bindTempAuthKey#cdd42a05 perm_auth_key_id:long nonce:long expires_at:int encrypted_message:bytes = Bool;
|
||||
|
||||
[bindRequestData appendInt32:(int32_t)0xcdd42a05];
|
||||
[bindRequestData appendInt64:_persistentKey.authKeyId];
|
||||
[bindRequestData appendInt64:nonce];
|
||||
[bindRequestData appendInt32:expiresAt];
|
||||
[bindRequestData appendTLBytes:encryptedMessage];
|
||||
|
||||
MTOutgoingMessage *outgoingMessage = [[MTOutgoingMessage alloc] initWithData:bindRequestData.data metadata:[NSString stringWithFormat:@"auth.bindTempAuthKey"] additionalDebugDescription:nil shortMetadata:@"auth.bindTempAuthKey" messageId:bindingMessageId messageSeqNo:bindingSeqNo];
|
||||
|
||||
return [[MTMessageTransaction alloc] initWithMessagePayload:@[outgoingMessage] prepared:nil failed:nil completion:^(NSDictionary *messageInternalIdToTransactionId, NSDictionary *messageInternalIdToPreparedMessage, __unused NSDictionary *messageInternalIdToQuickAckId) {
|
||||
MTPreparedMessage *preparedMessage = messageInternalIdToPreparedMessage[outgoingMessage.internalId];
|
||||
if (preparedMessage != nil && messageInternalIdToTransactionId[outgoingMessage.internalId] != nil) {
|
||||
_currentMessageId = preparedMessage.messageId;
|
||||
_currentTransactionId = messageInternalIdToTransactionId[outgoingMessage.internalId];
|
||||
}
|
||||
}];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)__unused mtProto messageDeliveryFailed:(int64_t)messageId {
|
||||
if (messageId == _currentMessageId) {
|
||||
_currentMessageId = 0;
|
||||
_currentTransactionId = nil;
|
||||
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)mtProto transactionsMayHaveFailed:(NSArray *)transactionIds {
|
||||
if (_currentTransactionId != nil && [transactionIds containsObject:_currentTransactionId]) {
|
||||
_currentTransactionId = nil;
|
||||
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtProtoAllTransactionsMayHaveFailed:(MTProto *)mtProto {
|
||||
if (_currentTransactionId != nil) {
|
||||
_currentTransactionId = nil;
|
||||
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtProtoDidChangeSession:(MTProto *)mtProto {
|
||||
_currentMessageId = 0;
|
||||
_currentTransactionId = nil;
|
||||
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
|
||||
- (void)mtProtoServerDidChangeSession:(MTProto *)mtProto firstValidMessageId:(int64_t)firstValidMessageId messageIdsInFirstValidContainer:(NSArray *)messageIdsInFirstValidContainer {
|
||||
if (_currentMessageId != 0 && _currentMessageId < firstValidMessageId && ![messageIdsInFirstValidContainer containsObject:@(_currentMessageId)]) {
|
||||
_currentMessageId = 0;
|
||||
_currentTransactionId = nil;
|
||||
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector {
|
||||
if ([message.body isKindOfClass:[MTRpcResultMessage class]]) {
|
||||
MTRpcResultMessage *rpcResultMessage = message.body;
|
||||
if (rpcResultMessage.requestMessageId == _currentMessageId) {
|
||||
bool success = false;
|
||||
if (rpcResultMessage.data.length >= 4) {
|
||||
uint32_t signature = 0;
|
||||
[rpcResultMessage.data getBytes:&signature range:NSMakeRange(0, 4)];
|
||||
|
||||
//boolTrue#997275b5 = Bool;
|
||||
if (signature == 0x997275b5U) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
_completion(success);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@ -114,7 +114,34 @@
|
||||
|
||||
@end
|
||||
|
||||
@interface MTContext () <MTDiscoverDatacenterAddressActionDelegate, MTDatacenterAuthActionDelegate, MTDatacenterTransferAuthActionDelegate>
|
||||
typedef int64_t MTDatacenterAuthInfoMapKey;
|
||||
|
||||
typedef struct {
|
||||
int32_t datacenterId;
|
||||
MTDatacenterAuthInfoSelector selector;
|
||||
} MTDatacenterAuthInfoMapKeyStruct;
|
||||
|
||||
static MTDatacenterAuthInfoMapKey authInfoMapKey(int32_t datacenterId, MTDatacenterAuthInfoSelector selector) {
|
||||
int64_t result = (((int64_t)(selector)) << 32) | ((int64_t)(datacenterId));
|
||||
return result;
|
||||
}
|
||||
|
||||
static NSNumber *authInfoMapIntegerKey(int32_t datacenterId, MTDatacenterAuthInfoSelector selector) {
|
||||
return [NSNumber numberWithLongLong:authInfoMapKey(datacenterId, selector)];
|
||||
}
|
||||
|
||||
static MTDatacenterAuthInfoMapKeyStruct parseAuthInfoMapKey(int64_t key) {
|
||||
MTDatacenterAuthInfoMapKeyStruct result;
|
||||
result.datacenterId = (int32_t)(key & 0x7fffffff);
|
||||
result.selector = (int32_t)(((key >> 32) & 0x7fffffff));
|
||||
return result;
|
||||
}
|
||||
|
||||
static MTDatacenterAuthInfoMapKeyStruct parseAuthInfoMapKeyInteger(NSNumber *key) {
|
||||
return parseAuthInfoMapKey([key longLongValue]);
|
||||
}
|
||||
|
||||
@interface MTContext () <MTDiscoverDatacenterAddressActionDelegate, MTDatacenterTransferAuthActionDelegate>
|
||||
{
|
||||
int64_t _uniqueId;
|
||||
|
||||
@ -127,7 +154,7 @@
|
||||
NSMutableDictionary<NSNumber *, NSMutableDictionary<MTDatacenterAddress *, MTTransportSchemeStats *> *> *_transportSchemeStats;
|
||||
MTTimer *_schemeStatsSyncTimer;
|
||||
|
||||
NSMutableDictionary *_datacenterAuthInfoById;
|
||||
NSMutableDictionary<NSNumber *, MTDatacenterAuthInfo *> *_datacenterAuthInfoById;
|
||||
|
||||
NSMutableDictionary *_datacenterPublicKeysById;
|
||||
|
||||
@ -138,8 +165,7 @@
|
||||
MTSignal *_discoverBackupAddressListSignal;
|
||||
|
||||
NSMutableDictionary *_discoverDatacenterAddressActions;
|
||||
NSMutableDictionary *_datacenterAuthActions;
|
||||
NSMutableDictionary *_datacenterTempAuthActions;
|
||||
NSMutableDictionary<NSNumber *, MTDatacenterAuthAction *> *_datacenterAuthActions;
|
||||
NSMutableDictionary *_datacenterTransferAuthActions;
|
||||
|
||||
NSMutableDictionary<NSNumber *, NSNumber *> *_datacenterCheckKeyRemovedActionTimestamps;
|
||||
@ -201,6 +227,11 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
_apiEnvironment = apiEnvironment;
|
||||
_isTestingEnvironment = isTestingEnvironment;
|
||||
_useTempAuthKeys = useTempAuthKeys;
|
||||
#if DEBUG
|
||||
_tempKeyExpiration = 1 * 60 * 60;
|
||||
#else
|
||||
_tempKeyExpiration = 1 * 60 * 60;
|
||||
#endif
|
||||
|
||||
_datacenterSeedAddressSetById = [[NSMutableDictionary alloc] init];
|
||||
|
||||
@ -218,7 +249,6 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
|
||||
_discoverDatacenterAddressActions = [[NSMutableDictionary alloc] init];
|
||||
_datacenterAuthActions = [[NSMutableDictionary alloc] init];
|
||||
_datacenterTempAuthActions = [[NSMutableDictionary alloc] init];
|
||||
_datacenterTransferAuthActions = [[NSMutableDictionary alloc] init];
|
||||
_datacenterCheckKeyRemovedActionTimestamps = [[NSMutableDictionary alloc] init];
|
||||
_datacenterCheckKeyRemovedActions = [[NSMutableDictionary alloc] init];
|
||||
@ -258,9 +288,6 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
NSDictionary *datacenterAuthActions = _datacenterAuthActions;
|
||||
_datacenterAuthActions = nil;
|
||||
|
||||
NSDictionary *datacenterTempAuthActions = _datacenterTempAuthActions;
|
||||
_datacenterTempAuthActions = nil;
|
||||
|
||||
NSDictionary *discoverDatacenterAddressActions = _discoverDatacenterAddressActions;
|
||||
_discoverDatacenterAddressActions = nil;
|
||||
|
||||
@ -284,17 +311,9 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
[action cancel];
|
||||
}
|
||||
|
||||
for (NSNumber *nDatacenterId in datacenterAuthActions)
|
||||
for (NSNumber *key in datacenterAuthActions)
|
||||
{
|
||||
MTDatacenterAuthAction *action = datacenterAuthActions[nDatacenterId];
|
||||
action.delegate = nil;
|
||||
[action cancel];
|
||||
}
|
||||
|
||||
for (NSNumber *nDatacenterId in datacenterTempAuthActions)
|
||||
{
|
||||
MTDatacenterAuthAction *action = datacenterTempAuthActions[nDatacenterId];
|
||||
action.delegate = nil;
|
||||
MTDatacenterAuthAction *action = datacenterAuthActions[key];
|
||||
[action cancel];
|
||||
}
|
||||
|
||||
@ -360,6 +379,14 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
NSDictionary *datacenterAuthInfoById = [keychain objectForKey:@"datacenterAuthInfoById" group:@"persistent"];
|
||||
if (datacenterAuthInfoById != nil) {
|
||||
_datacenterAuthInfoById = [[NSMutableDictionary alloc] initWithDictionary:datacenterAuthInfoById];
|
||||
#if DEBUG
|
||||
/*NSArray<NSNumber *> *keys = [_datacenterAuthInfoById allKeys];
|
||||
for (NSNumber *key in keys) {
|
||||
if (parseAuthInfoMapKeyInteger(key).selector != MTDatacenterAuthInfoSelectorPersistent) {
|
||||
[_datacenterAuthInfoById removeObjectForKey:key];
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
}
|
||||
|
||||
NSDictionary *datacenterPublicKeysById = [keychain objectForKey:@"datacenterPublicKeysById" group:@"ephemeral"];
|
||||
@ -582,29 +609,46 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo
|
||||
- (void)updateAuthInfoForDatacenterWithId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)authInfo selector:(MTDatacenterAuthInfoSelector)selector
|
||||
{
|
||||
[[MTContext contextQueue] dispatchOnQueue:^
|
||||
{
|
||||
if (datacenterId != 0)
|
||||
{
|
||||
if (MTLogEnabled()) {
|
||||
MTLog(@"[MTContext#%x: auth info updated for %d to %@]", (int)self, datacenterId, authInfo);
|
||||
}
|
||||
NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector);
|
||||
|
||||
bool wasNil = _datacenterAuthInfoById[infoKey] == nil;
|
||||
|
||||
if (authInfo != nil) {
|
||||
_datacenterAuthInfoById[@(datacenterId)] = authInfo;
|
||||
_datacenterAuthInfoById[infoKey] = authInfo;
|
||||
} else {
|
||||
[_datacenterAuthInfoById removeObjectForKey:@(datacenterId)];
|
||||
if (_datacenterAuthInfoById[infoKey] == nil) {
|
||||
return;
|
||||
}
|
||||
[_datacenterAuthInfoById removeObjectForKey:infoKey];
|
||||
}
|
||||
|
||||
if (MTLogEnabled()) {
|
||||
MTLog(@"[MTContext#%x: auth info updated for %d selector %d to %@]", (int)self, datacenterId, selector, authInfo);
|
||||
}
|
||||
|
||||
[_keychain setObject:_datacenterAuthInfoById forKey:@"datacenterAuthInfoById" group:@"persistent"];
|
||||
|
||||
NSArray *currentListeners = [[NSArray alloc] initWithArray:_changeListeners];
|
||||
|
||||
for (id<MTContextChangeListener> listener in currentListeners)
|
||||
{
|
||||
if ([listener respondsToSelector:@selector(contextDatacenterAuthInfoUpdated:datacenterId:authInfo:)])
|
||||
[listener contextDatacenterAuthInfoUpdated:self datacenterId:datacenterId authInfo:authInfo];
|
||||
if ([listener respondsToSelector:@selector(contextDatacenterAuthInfoUpdated:datacenterId:authInfo:selector:)])
|
||||
[listener contextDatacenterAuthInfoUpdated:self datacenterId:datacenterId authInfo:authInfo selector:selector];
|
||||
}
|
||||
|
||||
if (wasNil && authInfo != nil && selector == MTDatacenterAuthInfoSelectorPersistent) {
|
||||
for (NSNumber *key in _datacenterAuthActions) {
|
||||
MTDatacenterAuthInfoMapKeyStruct parsedKey = parseAuthInfoMapKeyInteger(key);
|
||||
if (parsedKey.datacenterId == datacenterId && parsedKey.selector != MTDatacenterAuthInfoSelectorPersistent) {
|
||||
[_datacenterAuthActions[key] execute:self datacenterId:datacenterId];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}];
|
||||
@ -864,10 +908,11 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
return results;
|
||||
}
|
||||
|
||||
- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId {
|
||||
- (MTDatacenterAuthInfo *)authInfoForDatacenterWithId:(NSInteger)datacenterId selector:(MTDatacenterAuthInfoSelector)selector {
|
||||
__block MTDatacenterAuthInfo *result = nil;
|
||||
[[MTContext contextQueue] dispatchOnQueue:^{
|
||||
result = _datacenterAuthInfoById[@(datacenterId)];
|
||||
NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector);
|
||||
result = _datacenterAuthInfoById[infoKey];
|
||||
} synchronous:true];
|
||||
|
||||
return result;
|
||||
@ -1251,48 +1296,44 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn
|
||||
- (void)authInfoForDatacenterWithIdRequired:(NSInteger)datacenterId isCdn:(bool)isCdn selector:(MTDatacenterAuthInfoSelector)selector
|
||||
{
|
||||
[[MTContext contextQueue] dispatchOnQueue:^
|
||||
{
|
||||
if (_datacenterAuthActions[@(datacenterId)] == nil)
|
||||
{
|
||||
MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithTempAuth:false tempAuthKeyType:MTDatacenterAuthTempKeyTypeMain bindKey:nil];
|
||||
authAction.delegate = self;
|
||||
_datacenterAuthActions[@(datacenterId)] = authAction;
|
||||
[authAction execute:self datacenterId:datacenterId isCdn:isCdn];
|
||||
}
|
||||
}];
|
||||
}
|
||||
NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector);
|
||||
|
||||
- (void)tempAuthKeyForDatacenterWithIdRequired:(NSInteger)datacenterId keyType:(MTDatacenterAuthTempKeyType)keyType {
|
||||
if (_datacenterAuthActions[infoKey] == nil)
|
||||
{
|
||||
__weak MTContext *weakSelf = self;
|
||||
MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:selector isCdn:isCdn completion:^(MTDatacenterAuthAction *action, __unused bool success) {
|
||||
[[MTContext contextQueue] dispatchOnQueue:^{
|
||||
if (_datacenterTempAuthActions[@(datacenterId)] == nil) {
|
||||
MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithTempAuth:true tempAuthKeyType:keyType bindKey:nil];
|
||||
authAction.delegate = self;
|
||||
_datacenterTempAuthActions[@(datacenterId)] = authAction;
|
||||
[authAction execute:self datacenterId:datacenterId isCdn:false];
|
||||
__strong MTContext *strongSelf = weakSelf;
|
||||
if (strongSelf == nil) {
|
||||
return;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)datacenterAuthActionCompleted:(MTDatacenterAuthAction *)action
|
||||
{
|
||||
[[MTContext contextQueue] dispatchOnQueue:^
|
||||
{
|
||||
if (action.tempAuth) {
|
||||
for (NSNumber *nDatacenterId in _datacenterTempAuthActions) {
|
||||
if (_datacenterTempAuthActions[nDatacenterId] == action) {
|
||||
[_datacenterTempAuthActions removeObjectForKey:nDatacenterId];
|
||||
|
||||
for (NSNumber *key in _datacenterAuthActions) {
|
||||
if (_datacenterAuthActions[key] == action) {
|
||||
[_datacenterAuthActions removeObjectForKey:key];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (NSNumber *nDatacenterId in _datacenterAuthActions) {
|
||||
if (_datacenterAuthActions[nDatacenterId] == action) {
|
||||
[_datacenterAuthActions removeObjectForKey:nDatacenterId];
|
||||
}];
|
||||
}];
|
||||
_datacenterAuthActions[infoKey] = authAction;
|
||||
|
||||
switch (selector) {
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMain:
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMedia: {
|
||||
if ([self authInfoForDatacenterWithId:datacenterId selector:MTDatacenterAuthInfoSelectorPersistent] == nil) {
|
||||
[self authInfoForDatacenterWithIdRequired:datacenterId isCdn:false selector:MTDatacenterAuthInfoSelectorPersistent];
|
||||
} else {
|
||||
[authAction execute:self datacenterId:datacenterId];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
[authAction execute:self datacenterId:datacenterId];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1357,21 +1398,11 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
|
||||
- (void)updatePeriodicTasks
|
||||
{
|
||||
[[MTContext contextQueue] dispatchOnQueue:^
|
||||
{
|
||||
int64_t saltsRequiredAtLeastUntilMessageId = (int64_t)(([self globalTime] + 24 * 60.0 * 60.0) * 4294967296);
|
||||
|
||||
[_datacenterAuthInfoById enumerateKeysAndObjectsUsingBlock:^(NSNumber *nDatacenterId, MTDatacenterAuthInfo *authInfo, __unused BOOL *stop)
|
||||
{
|
||||
if ([authInfo authSaltForMessageId:saltsRequiredAtLeastUntilMessageId == 0]) {
|
||||
}
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)checkIfLoggedOut:(NSInteger)datacenterId {
|
||||
[[MTContext contextQueue] dispatchOnQueue:^{
|
||||
MTDatacenterAuthInfo *authInfo = [self authInfoForDatacenterWithId:datacenterId];
|
||||
MTDatacenterAuthInfo *authInfo = [self authInfoForDatacenterWithId:datacenterId selector:MTDatacenterAuthInfoSelectorPersistent];
|
||||
if (authInfo == nil || authInfo.authKey == nil) {
|
||||
return;
|
||||
}
|
||||
@ -1382,7 +1413,7 @@ static int32_t fixedTimeDifferenceValue = 0;
|
||||
_datacenterCheckKeyRemovedActionTimestamps[@(datacenterId)] = currentTimestamp;
|
||||
[_datacenterCheckKeyRemovedActions[@(datacenterId)] dispose];
|
||||
__weak MTContext *weakSelf = self;
|
||||
_datacenterCheckKeyRemovedActions[@(datacenterId)] = [[MTDiscoverConnectionSignals checkIfAuthKeyRemovedWithContext:self datacenterId:datacenterId authKey:authInfo.authKey] startWithNext:^(NSNumber *isRemoved) {
|
||||
_datacenterCheckKeyRemovedActions[@(datacenterId)] = [[MTDiscoverConnectionSignals checkIfAuthKeyRemovedWithContext:self datacenterId:datacenterId authKey:[[MTDatacenterAuthKey alloc] initWithAuthKey:authInfo.authKey authKeyId:authInfo.authKeyId notBound:false]] startWithNext:^(NSNumber* isRemoved) {
|
||||
[[MTContext contextQueue] dispatchOnQueue:^{
|
||||
__strong MTContext *strongSelf = weakSelf;
|
||||
if (strongSelf == nil) {
|
||||
|
@ -12,13 +12,15 @@
|
||||
#import <MtProtoKit/MTSignal.h>
|
||||
#import <MtProtoKit/MTDatacenterAuthMessageService.h>
|
||||
#import <MtProtoKit/MTRequestMessageService.h>
|
||||
#import <MtProtoKit/MTBindKeyMessageService.h>
|
||||
#import "MTBuffer.h"
|
||||
|
||||
@interface MTDatacenterAuthAction () <MTDatacenterAuthMessageServiceDelegate>
|
||||
{
|
||||
void (^_completion)(MTDatacenterAuthAction *, bool);
|
||||
|
||||
bool _isCdn;
|
||||
MTDatacenterAuthTempKeyType _tempAuthKeyType;
|
||||
MTDatacenterAuthKey *_bindKey;
|
||||
MTDatacenterAuthInfoSelector _authKeyInfoSelector;
|
||||
|
||||
NSInteger _datacenterId;
|
||||
__weak MTContext *_context;
|
||||
@ -26,71 +28,61 @@
|
||||
bool _awaitingAddresSetUpdate;
|
||||
MTProto *_authMtProto;
|
||||
MTProto *_bindMtProto;
|
||||
|
||||
MTMetaDisposable *_verifyDisposable;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTDatacenterAuthAction
|
||||
|
||||
- (instancetype)initWithTempAuth:(bool)tempAuth tempAuthKeyType:(MTDatacenterAuthTempKeyType)tempAuthKeyType bindKey:(MTDatacenterAuthKey *)bindKey {
|
||||
- (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn completion:(void (^)(MTDatacenterAuthAction *, bool))completion {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_tempAuth = tempAuth;
|
||||
_tempAuthKeyType = tempAuthKeyType;
|
||||
_bindKey = bindKey;
|
||||
_verifyDisposable = [[MTMetaDisposable alloc] init];
|
||||
_authKeyInfoSelector = authKeyInfoSelector;
|
||||
_isCdn = isCdn;
|
||||
_completion = [completion copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
- (void)dealloc {
|
||||
[self cleanup];
|
||||
}
|
||||
|
||||
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId isCdn:(bool)isCdn
|
||||
{
|
||||
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId {
|
||||
_datacenterId = datacenterId;
|
||||
_context = context;
|
||||
_isCdn = isCdn;
|
||||
|
||||
if (_datacenterId != 0 && context != nil)
|
||||
{
|
||||
bool alreadyCompleted = false;
|
||||
MTDatacenterAuthInfo *currentAuthInfo = [context authInfoForDatacenterWithId:_datacenterId];
|
||||
if (currentAuthInfo != nil && _bindKey == nil) {
|
||||
if (_tempAuth) {
|
||||
if ([currentAuthInfo tempAuthKeyWithType:_tempAuthKeyType] != nil) {
|
||||
|
||||
MTDatacenterAuthInfo *currentAuthInfo = [context authInfoForDatacenterWithId:_datacenterId selector:_authKeyInfoSelector];
|
||||
if (currentAuthInfo != nil) {
|
||||
alreadyCompleted = true;
|
||||
}
|
||||
} else {
|
||||
alreadyCompleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (alreadyCompleted) {
|
||||
[self complete];
|
||||
} else {
|
||||
_authMtProto = [[MTProto alloc] initWithContext:context datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
|
||||
_authMtProto.cdn = isCdn;
|
||||
_authMtProto.cdn = _isCdn;
|
||||
_authMtProto.useUnauthorizedMode = true;
|
||||
if (_tempAuth) {
|
||||
switch (_tempAuthKeyType) {
|
||||
case MTDatacenterAuthTempKeyTypeMain:
|
||||
bool tempAuth = false;
|
||||
switch (_authKeyInfoSelector) {
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMain:
|
||||
tempAuth = true;
|
||||
_authMtProto.media = false;
|
||||
break;
|
||||
case MTDatacenterAuthTempKeyTypeMedia:
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMedia:
|
||||
tempAuth = true;
|
||||
_authMtProto.media = true;
|
||||
_authMtProto.enforceMedia = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MTDatacenterAuthMessageService *authService = [[MTDatacenterAuthMessageService alloc] initWithContext:context tempAuth:_tempAuth];
|
||||
MTDatacenterAuthMessageService *authService = [[MTDatacenterAuthMessageService alloc] initWithContext:context tempAuth:tempAuth];
|
||||
authService.delegate = self;
|
||||
[_authMtProto addMessageService:authService];
|
||||
}
|
||||
@ -104,45 +96,71 @@
|
||||
}
|
||||
|
||||
- (void)completeWithAuthKey:(MTDatacenterAuthKey *)authKey timestamp:(int64_t)timestamp {
|
||||
if (_tempAuth) {
|
||||
if (MTLogEnabled()) {
|
||||
MTLog(@"[MTDatacenterAuthAction#%p@%p: completeWithAuthKey %lld selector %d]", self, _context, authKey.authKeyId, _authKeyInfoSelector);
|
||||
}
|
||||
|
||||
switch (_authKeyInfoSelector) {
|
||||
case MTDatacenterAuthInfoSelectorPersistent: {
|
||||
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil];
|
||||
|
||||
MTContext *context = _context;
|
||||
[context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector];
|
||||
[self complete];
|
||||
}
|
||||
break;
|
||||
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMain:
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMedia: {
|
||||
MTContext *mainContext = _context;
|
||||
if (mainContext != nil) {
|
||||
if (_bindKey != nil) {
|
||||
MTDatacenterAuthInfo *persistentAuthInfo = [mainContext authInfoForDatacenterWithId:_datacenterId selector:MTDatacenterAuthInfoSelectorPersistent];
|
||||
if (persistentAuthInfo != nil) {
|
||||
_bindMtProto = [[MTProto alloc] initWithContext:mainContext datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
|
||||
_bindMtProto.cdn = false;
|
||||
_bindMtProto.useUnauthorizedMode = false;
|
||||
_bindMtProto.useTempAuthKeys = true;
|
||||
_bindMtProto.useExplicitAuthKey = authKey;
|
||||
|
||||
switch (_authKeyInfoSelector) {
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMain:
|
||||
_bindMtProto.media = false;
|
||||
break;
|
||||
case MTDatacenterAuthInfoSelectorEphemeralMedia:
|
||||
_bindMtProto.media = true;
|
||||
_bindMtProto.enforceMedia = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
__weak MTDatacenterAuthAction *weakSelf = self;
|
||||
_bindMtProto.tempAuthKeyBindingResultUpdated = ^(bool success) {
|
||||
[_bindMtProto addMessageService:[[MTBindKeyMessageService alloc] initWithPersistentKey:[[MTDatacenterAuthKey alloc] initWithAuthKey:persistentAuthInfo.authKey authKeyId:persistentAuthInfo.authKeyId notBound:false] ephemeralKey:authKey completion:^(bool success) {
|
||||
__strong MTDatacenterAuthAction *strongSelf = weakSelf;
|
||||
if (strongSelf == nil) {
|
||||
return;
|
||||
}
|
||||
[strongSelf->_bindMtProto stop];
|
||||
if (strongSelf->_completedWithResult) {
|
||||
strongSelf->_completedWithResult(success);
|
||||
}
|
||||
};
|
||||
_bindMtProto.useExplicitAuthKey = authKey;
|
||||
[_bindMtProto resume];
|
||||
} else {
|
||||
MTContext *context = _context;
|
||||
[context performBatchUpdates:^{
|
||||
MTDatacenterAuthInfo *authInfo = [context authInfoForDatacenterWithId:_datacenterId];
|
||||
if (authInfo != nil) {
|
||||
authInfo = [authInfo withUpdatedTempAuthKeyWithType:_tempAuthKeyType key:authKey];
|
||||
[context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo];
|
||||
}
|
||||
}];
|
||||
[self complete];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil mainTempAuthKey:nil mediaTempAuthKey:nil];
|
||||
|
||||
MTContext *context = _context;
|
||||
[context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo];
|
||||
[self complete];
|
||||
if (success) {
|
||||
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:authKey.authKey authKeyId:authKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:timestamp lastValidMessageId:timestamp + (29.0 * 60.0) * 4294967296]] authKeyAttributes:nil];
|
||||
|
||||
[strongSelf->_context updateAuthInfoForDatacenterWithId:strongSelf->_datacenterId authInfo:authInfo selector:strongSelf->_authKeyInfoSelector];
|
||||
|
||||
[strongSelf complete];
|
||||
} else {
|
||||
[strongSelf fail];
|
||||
}
|
||||
}]];
|
||||
[_bindMtProto resume];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,7 +171,10 @@
|
||||
|
||||
[authMtProto stop];
|
||||
|
||||
[_verifyDisposable dispose];
|
||||
MTProto *bindMtProto = _bindMtProto;
|
||||
_bindMtProto = nil;
|
||||
|
||||
[bindMtProto stop];
|
||||
}
|
||||
|
||||
- (void)cancel
|
||||
@ -162,18 +183,17 @@
|
||||
[self fail];
|
||||
}
|
||||
|
||||
- (void)complete
|
||||
{
|
||||
id<MTDatacenterAuthActionDelegate> delegate = _delegate;
|
||||
if ([delegate respondsToSelector:@selector(datacenterAuthActionCompleted:)])
|
||||
[delegate datacenterAuthActionCompleted:self];
|
||||
- (void)complete {
|
||||
if (_completion) {
|
||||
_completion(self, true);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)fail
|
||||
{
|
||||
id<MTDatacenterAuthActionDelegate> delegate = _delegate;
|
||||
if ([delegate respondsToSelector:@selector(datacenterAuthActionCompleted:)])
|
||||
[delegate datacenterAuthActionCompleted:self];
|
||||
if (_completion) {
|
||||
_completion(self, false);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
@implementation MTDatacenterAuthInfo
|
||||
|
||||
- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes mainTempAuthKey:(MTDatacenterAuthKey *)mainTempAuthKey mediaTempAuthKey:(MTDatacenterAuthKey *)mediaTempAuthKey
|
||||
- (instancetype)initWithAuthKey:(NSData *)authKey authKeyId:(int64_t)authKeyId saltSet:(NSArray *)saltSet authKeyAttributes:(NSDictionary *)authKeyAttributes
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
@ -36,8 +36,6 @@
|
||||
_authKeyId = authKeyId;
|
||||
_saltSet = saltSet;
|
||||
_authKeyAttributes = authKeyAttributes;
|
||||
_mainTempAuthKey = mainTempAuthKey;
|
||||
_mediaTempAuthKey = mediaTempAuthKey;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -51,8 +49,6 @@
|
||||
_authKeyId = [aDecoder decodeInt64ForKey:@"authKeyId"];
|
||||
_saltSet = [aDecoder decodeObjectForKey:@"saltSet"];
|
||||
_authKeyAttributes = [aDecoder decodeObjectForKey:@"authKeyAttributes"];
|
||||
_mainTempAuthKey = [aDecoder decodeObjectForKey:@"tempAuthKey"];
|
||||
_mediaTempAuthKey = [aDecoder decodeObjectForKey:@"mediaTempAuthKey"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@ -63,8 +59,6 @@
|
||||
[aCoder encodeInt64:_authKeyId forKey:@"authKeyId"];
|
||||
[aCoder encodeObject:_saltSet forKey:@"saltSet"];
|
||||
[aCoder encodeObject:_authKeyAttributes forKey:@"authKeyAttributes"];
|
||||
[aCoder encodeObject:_mainTempAuthKey forKey:@"tempAuthKey"];
|
||||
[aCoder encodeObject:_mediaTempAuthKey forKey:@"mediaTempAuthKey"];
|
||||
}
|
||||
|
||||
- (int64_t)authSaltForMessageId:(int64_t)messageId
|
||||
@ -113,35 +107,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:mergedSaltSet authKeyAttributes:_authKeyAttributes mainTempAuthKey:_mainTempAuthKey mediaTempAuthKey:_mediaTempAuthKey];
|
||||
return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:mergedSaltSet authKeyAttributes:_authKeyAttributes];
|
||||
}
|
||||
|
||||
- (MTDatacenterAuthInfo *)withUpdatedAuthKeyAttributes:(NSDictionary *)authKeyAttributes {
|
||||
return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:authKeyAttributes mainTempAuthKey:_mainTempAuthKey mediaTempAuthKey:_mediaTempAuthKey];
|
||||
}
|
||||
|
||||
- (MTDatacenterAuthKey *)tempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type {
|
||||
switch (type) {
|
||||
case MTDatacenterAuthTempKeyTypeMain:
|
||||
return _mainTempAuthKey;
|
||||
case MTDatacenterAuthTempKeyTypeMedia:
|
||||
return _mediaTempAuthKey;
|
||||
default:
|
||||
NSAssert(false, @"unknown MTDatacenterAuthTempKeyType");
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (MTDatacenterAuthInfo *)withUpdatedTempAuthKeyWithType:(MTDatacenterAuthTempKeyType)type key:(MTDatacenterAuthKey *)key {
|
||||
switch (type) {
|
||||
case MTDatacenterAuthTempKeyTypeMain:
|
||||
return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:_authKeyAttributes mainTempAuthKey:key mediaTempAuthKey:_mediaTempAuthKey];
|
||||
case MTDatacenterAuthTempKeyTypeMedia:
|
||||
return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:_authKeyAttributes mainTempAuthKey:_mainTempAuthKey mediaTempAuthKey:key];
|
||||
default:
|
||||
NSAssert(false, @"unknown MTDatacenterAuthTempKeyType");
|
||||
return self;
|
||||
}
|
||||
return [[MTDatacenterAuthInfo alloc] initWithAuthKey:_authKey authKeyId:_authKeyId saltSet:_saltSet authKeyAttributes:authKeyAttributes];
|
||||
}
|
||||
|
||||
- (MTDatacenterAuthKey *)persistentAuthKey {
|
||||
|
@ -222,7 +222,7 @@ typedef enum {
|
||||
}
|
||||
}
|
||||
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
|
||||
{
|
||||
if (_currentStageTransactionId == nil)
|
||||
{
|
||||
@ -308,7 +308,7 @@ typedef enum {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
|
||||
{
|
||||
if (_stage == MTDatacenterAuthStagePQ && [message.body isKindOfClass:[MTResPqMessage class]])
|
||||
{
|
||||
@ -389,7 +389,7 @@ typedef enum {
|
||||
[innerDataBuffer appendBytes:_nonce.bytes length:_nonce.length];
|
||||
[innerDataBuffer appendBytes:_serverNonce.bytes length:_serverNonce.length];
|
||||
[innerDataBuffer appendBytes:_newNonce.bytes length:_newNonce.length];
|
||||
[innerDataBuffer appendInt32:60 * 60 * 32];
|
||||
[innerDataBuffer appendInt32:mtProto.context.tempKeyExpiration];
|
||||
|
||||
NSData *innerDataBytes = innerDataBuffer.data;
|
||||
|
||||
|
@ -249,12 +249,11 @@
|
||||
MTMetaDisposable *disposable = [[MTMetaDisposable alloc] init];
|
||||
|
||||
[[MTContext contextQueue] dispatchOnQueue:^{
|
||||
MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithTempAuth:true tempAuthKeyType:MTDatacenterAuthTempKeyTypeMain bindKey:authKey];
|
||||
action.completedWithResult = ^(bool success) {
|
||||
MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:MTDatacenterAuthInfoSelectorEphemeralMain isCdn:false completion:^(__unused MTDatacenterAuthAction *action, bool success) {
|
||||
[subscriber putNext:@(!success)];
|
||||
[subscriber putCompletion];
|
||||
};
|
||||
[action execute:context datacenterId:datacenterId isCdn:false];
|
||||
}];
|
||||
[action execute:context datacenterId:datacenterId];
|
||||
|
||||
[disposable setDisposable:[[MTBlockDisposable alloc] initWithBlock:^{
|
||||
[action cancel];
|
||||
|
@ -88,7 +88,7 @@
|
||||
[self fail];
|
||||
else
|
||||
{
|
||||
if ([context authInfoForDatacenterWithId:_targetDatacenterId] != nil)
|
||||
if ([context authInfoForDatacenterWithId:_targetDatacenterId selector:MTDatacenterAuthInfoSelectorPersistent] != nil)
|
||||
{
|
||||
_mtProto = [[MTProto alloc] initWithContext:context datacenterId:_targetDatacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
|
||||
_mtProto.useTempAuthKeys = useTempAuthKeys;
|
||||
@ -118,11 +118,11 @@
|
||||
[_requestService addRequest:request];
|
||||
}
|
||||
else
|
||||
[context authInfoForDatacenterWithIdRequired:_targetDatacenterId isCdn:false];
|
||||
[context authInfoForDatacenterWithIdRequired:_targetDatacenterId isCdn:false selector:MTDatacenterAuthInfoSelectorPersistent];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)__unused authInfo
|
||||
- (void)contextDatacenterAuthInfoUpdated:(MTContext *)context datacenterId:(NSInteger)datacenterId authInfo:(MTDatacenterAuthInfo *)__unused authInfo selector:(MTDatacenterAuthInfoSelector)selector
|
||||
{
|
||||
if (_context != context || !_awaitingAddresSetUpdate)
|
||||
return;
|
||||
|
File diff suppressed because it is too large
Load Diff
52
submodules/MtProtoKit/Sources/MTProtoEngine.m
Normal file
52
submodules/MtProtoKit/Sources/MTProtoEngine.m
Normal file
@ -0,0 +1,52 @@
|
||||
#import <MtProtoKit/MTProtoEngine.h>
|
||||
|
||||
#import "Utils/MTQueueLocalObject.h"
|
||||
#import <MtProtoKit/MTQueue.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MTProtoEngineImpl : NSObject {
|
||||
MTQueue *_queue;
|
||||
id<MTProtoPersistenceInterface> _persistenceInterface;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTProtoEngineImpl
|
||||
|
||||
- (instancetype)initWithQueue:(MTQueue *)queue persistenceInterface:(id<MTProtoPersistenceInterface>)persistenceInterface {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_queue = queue;
|
||||
_persistenceInterface = persistenceInterface;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface MTProtoEngine () {
|
||||
MTQueue *_queue;
|
||||
MTQueueLocalObject<MTProtoEngineImpl *> *_impl;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTProtoEngine
|
||||
|
||||
- (instancetype)initWithPersistenceInterface:(id<MTProtoPersistenceInterface>)persistenceInterface {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_queue = [[MTQueue alloc] init];
|
||||
__auto_type queue = _queue;
|
||||
_impl = [[MTQueueLocalObject<MTProtoEngineImpl
|
||||
*> alloc] initWithQueue:queue generator:^MTProtoEngineImpl *{
|
||||
return [[MTProtoEngineImpl alloc] initWithQueue:queue persistenceInterface:persistenceInterface];
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
48
submodules/MtProtoKit/Sources/MTProtoInstance.m
Normal file
48
submodules/MtProtoKit/Sources/MTProtoInstance.m
Normal file
@ -0,0 +1,48 @@
|
||||
#import <MtProtoKit/MTProtoInstance.h>
|
||||
|
||||
#import <MtProtoKit/MTQueue.h>
|
||||
#import "Utils/MTQueueLocalObject.h"
|
||||
|
||||
@interface MTProtoInstanceImpl : NSObject {
|
||||
MTQueue *_queue;
|
||||
MTProtoEngine *_engine;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTProtoInstanceImpl
|
||||
|
||||
- (instancetype)initWithQueue:(MTQueue *)queue engine:(MTProtoEngine *)engine {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_queue = queue;
|
||||
_engine = engine;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface MTProtoInstance () {
|
||||
MTQueue *_queue;
|
||||
MTQueueLocalObject<MTProtoInstanceImpl *> *_impl;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTProtoInstance
|
||||
|
||||
- (instancetype)initWithEngine:(MTProtoEngine *)engine {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_queue = [[MTQueue alloc] init];
|
||||
__auto_type queue = _queue;
|
||||
_impl = [[MTQueueLocalObject<MTProtoInstanceImpl
|
||||
*> alloc] initWithQueue:queue generator:^MTProtoInstanceImpl *{
|
||||
return [[MTProtoInstanceImpl alloc] initWithQueue:queue engine:engine];
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
@ -391,12 +391,12 @@
|
||||
return currentData;
|
||||
}
|
||||
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
|
||||
{
|
||||
NSMutableArray *messages = nil;
|
||||
NSMutableDictionary *requestInternalIdToMessageInternalId = nil;
|
||||
|
||||
bool requestsWillInitializeApi = _apiEnvironment != nil && ![_apiEnvironment.apiInitializationHash isEqualToString:[_context authInfoForDatacenterWithId:mtProto.datacenterId].authKeyAttributes[@"apiInitializationHash"]];
|
||||
bool requestsWillInitializeApi = _apiEnvironment != nil && ![_apiEnvironment.apiInitializationHash isEqualToString:[_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector].authKeyAttributes[@"apiInitializationHash"]];
|
||||
|
||||
CFAbsoluteTime currentTime = MTAbsoluteSystemTime();
|
||||
|
||||
@ -561,7 +561,7 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)message
|
||||
- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
|
||||
{
|
||||
if ([message.body isKindOfClass:[MTRpcResultMessage class]])
|
||||
{
|
||||
@ -610,13 +610,13 @@
|
||||
{
|
||||
rpcError = [[MTRpcError alloc] initWithErrorCode:500 errorDescription:@"TL_PARSING_ERROR"];
|
||||
[_context performBatchUpdates:^{
|
||||
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId];
|
||||
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector];
|
||||
|
||||
NSMutableDictionary *authKeyAttributes = [[NSMutableDictionary alloc] initWithDictionary:authInfo.authKeyAttributes];
|
||||
authKeyAttributes[@"apiInitializationHash"] = @"";
|
||||
|
||||
authInfo = [authInfo withUpdatedAuthKeyAttributes:authKeyAttributes];
|
||||
[_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo];
|
||||
[_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo selector:authInfoSelector];
|
||||
}];
|
||||
}
|
||||
}
|
||||
@ -636,7 +636,7 @@
|
||||
|
||||
if (rpcResult != nil && request.requestContext.willInitializeApi)
|
||||
{
|
||||
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId];
|
||||
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector];
|
||||
|
||||
if (![_apiEnvironment.apiInitializationHash isEqualToString:authInfo.authKeyAttributes[@"apiInitializationHash"]])
|
||||
{
|
||||
@ -644,7 +644,7 @@
|
||||
authKeyAttributes[@"apiInitializationHash"] = _apiEnvironment.apiInitializationHash;
|
||||
|
||||
authInfo = [authInfo withUpdatedAuthKeyAttributes:authKeyAttributes];
|
||||
[_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo];
|
||||
[_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo selector:authInfoSelector];
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,13 +726,13 @@
|
||||
{
|
||||
[_context performBatchUpdates:^
|
||||
{
|
||||
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId];
|
||||
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:mtProto.datacenterId selector:authInfoSelector];
|
||||
|
||||
NSMutableDictionary *authKeyAttributes = [[NSMutableDictionary alloc] initWithDictionary:authInfo.authKeyAttributes];
|
||||
[authKeyAttributes removeObjectForKey:@"apiInitializationHash"];
|
||||
|
||||
authInfo = [authInfo withUpdatedAuthKeyAttributes:authKeyAttributes];
|
||||
[_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo];
|
||||
[_context updateAuthInfoForDatacenterWithId:mtProto.datacenterId authInfo:authInfo selector:authInfoSelector];
|
||||
}];
|
||||
} else if (rpcError.errorCode == 406) {
|
||||
if (_didReceiveSoftAuthResetError) {
|
||||
|
@ -41,7 +41,7 @@
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
|
||||
{
|
||||
if (_currentRequestMessageId == 0 || _currentRequestTransactionId == nil)
|
||||
{
|
||||
@ -121,7 +121,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
|
||||
{
|
||||
if (message.messageId == _messageId)
|
||||
{
|
||||
|
@ -747,7 +747,7 @@ static const NSTimeInterval MTTcpTransportSleepWatchdogTimeout = 60.0;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)incomingMessage
|
||||
- (void)mtProto:(MTProto *)__unused mtProto receivedMessage:(MTIncomingMessage *)incomingMessage authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
|
||||
{
|
||||
if ([incomingMessage.body isKindOfClass:[MTPongMessage class]])
|
||||
{
|
||||
|
@ -45,7 +45,7 @@
|
||||
[mtProto requestTransportTransaction];
|
||||
}
|
||||
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto
|
||||
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
|
||||
{
|
||||
if (_currentTransactionId == nil)
|
||||
{
|
||||
@ -127,7 +127,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message
|
||||
- (void)mtProto:(MTProto *)mtProto receivedMessage:(MTIncomingMessage *)message authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
|
||||
{
|
||||
if ([message.body isKindOfClass:[MTFutureSaltsMessage class]] && ((MTFutureSaltsMessage *)message.body).requestMessageId == _currentMessageId)
|
||||
{
|
||||
|
14
submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.h
Normal file
14
submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.h
Normal file
@ -0,0 +1,14 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class MTQueue;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MTQueueLocalObject<__covariant T> : NSObject
|
||||
|
||||
- (instancetype)initWithQueue:(MTQueue *)queue generator:(T(^)())generator;
|
||||
- (void)with:(void (^)(T))f;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
56
submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.m
Normal file
56
submodules/MtProtoKit/Sources/Utils/MTQueueLocalObject.m
Normal file
@ -0,0 +1,56 @@
|
||||
#import "MTQueueLocalObject.h"
|
||||
#import <MtProtoKit/MTQueue.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface MTQueueLocalObjectHolder : NSObject
|
||||
|
||||
@property (nonatomic, assign) CFTypeRef impl;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTQueueLocalObjectHolder
|
||||
|
||||
@end
|
||||
|
||||
@interface MTQueueLocalObject () {
|
||||
MTQueue *_queue;
|
||||
MTQueueLocalObjectHolder *_holder;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MTQueueLocalObject
|
||||
|
||||
- (instancetype)initWithQueue:(MTQueue *)queue generator:(id(^)())generator {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
_queue = queue;
|
||||
_holder = [[MTQueueLocalObjectHolder alloc] init];
|
||||
__auto_type holder = _holder;
|
||||
[queue dispatchOnQueue:^{
|
||||
id value = generator();
|
||||
holder.impl = CFBridgingRetain(value);
|
||||
} synchronous:false];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
__auto_type holder = _holder;
|
||||
[_queue dispatchOnQueue:^{
|
||||
CFBridgingRelease(holder.impl);
|
||||
} synchronous:false];
|
||||
}
|
||||
|
||||
- (void)with:(void (^)(id))f {
|
||||
__auto_type holder = _holder;
|
||||
[_queue dispatchOnQueue:^{
|
||||
id value = (__bridge id)holder.impl;
|
||||
f(value);
|
||||
} synchronous:false];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -103,8 +103,8 @@ public class UnauthorizedAccount {
|
||||
datacenterIds.append(contentsOf: [4])
|
||||
}
|
||||
for id in datacenterIds {
|
||||
if network.context.authInfoForDatacenter(withId: id) == nil {
|
||||
network.context.authInfoForDatacenter(withIdRequired: id, isCdn: false)
|
||||
if network.context.authInfoForDatacenter(withId: id, selector: .persistent) == nil {
|
||||
network.context.authInfoForDatacenter(withIdRequired: id, isCdn: false, selector: .ephemeralMain)
|
||||
}
|
||||
}
|
||||
network.context.beginExplicitBackupAddressDiscovery()
|
||||
@ -128,7 +128,7 @@ public class UnauthorizedAccount {
|
||||
}
|
||||
}
|
||||
|> mapToSignal { (localizationSettings, proxySettings, networkSettings) -> Signal<UnauthorizedAccount, NoError> in
|
||||
return initializedNetwork(arguments: self.networkArguments, supplementary: false, datacenterId: Int(masterDatacenterId), keychain: keychain, basePath: self.basePath, testingEnvironment: self.testingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
return initializedNetwork(accountId: self.id, arguments: self.networkArguments, supplementary: false, datacenterId: Int(masterDatacenterId), keychain: keychain, basePath: self.basePath, testingEnvironment: self.testingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
|> map { network in
|
||||
let updated = UnauthorizedAccount(networkArguments: self.networkArguments, id: self.id, rootPath: self.rootPath, basePath: self.basePath, testingEnvironment: self.testingEnvironment, postbox: self.postbox, network: network)
|
||||
updated.shouldBeServiceTaskMaster.set(self.shouldBeServiceTaskMaster.get())
|
||||
@ -243,7 +243,7 @@ public func accountWithId(accountManager: AccountManager, networkArguments: Netw
|
||||
let backupState = AuthorizedAccountState(isTestingEnvironment: beginWithTestingEnvironment, masterDatacenterId: backupData.masterDatacenterId, peerId: PeerId(backupData.peerId), state: nil)
|
||||
state = backupState
|
||||
let dict = NSMutableDictionary()
|
||||
dict.setObject(MTDatacenterAuthInfo(authKey: backupData.masterDatacenterKey, authKeyId: backupData.masterDatacenterKeyId, saltSet: [], authKeyAttributes: [:], mainTempAuthKey: nil, mediaTempAuthKey: nil), forKey: backupData.masterDatacenterId as NSNumber)
|
||||
dict.setObject(MTDatacenterAuthInfo(authKey: backupData.masterDatacenterKey, authKeyId: backupData.masterDatacenterKeyId, saltSet: [], authKeyAttributes: [:]), forKey: backupData.masterDatacenterId as NSNumber)
|
||||
let data = NSKeyedArchiver.archivedData(withRootObject: dict)
|
||||
transaction.setState(backupState)
|
||||
transaction.setKeychainEntry(data, forKey: "persistent:datacenterAuthInfoById")
|
||||
@ -257,7 +257,7 @@ public func accountWithId(accountManager: AccountManager, networkArguments: Netw
|
||||
if let accountState = accountState {
|
||||
switch accountState {
|
||||
case let unauthorizedState as UnauthorizedAccountState:
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: unauthorizedState.isTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
return initializedNetwork(accountId: id, arguments: networkArguments, supplementary: supplementary, datacenterId: Int(unauthorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: unauthorizedState.isTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
|> map { network -> AccountResult in
|
||||
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: unauthorizedState.isTestingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
|
||||
}
|
||||
@ -266,7 +266,7 @@ public func accountWithId(accountManager: AccountManager, networkArguments: Netw
|
||||
return (transaction.getPeer(authorizedState.peerId) as? TelegramUser)?.phone
|
||||
}
|
||||
|> mapToSignal { phoneNumber in
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: authorizedState.isTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: phoneNumber)
|
||||
return initializedNetwork(accountId: id, arguments: networkArguments, supplementary: supplementary, datacenterId: Int(authorizedState.masterDatacenterId), keychain: keychain, basePath: path, testingEnvironment: authorizedState.isTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: phoneNumber)
|
||||
|> map { network -> AccountResult in
|
||||
return .authorized(Account(accountManager: accountManager, id: id, basePath: path, testingEnvironment: authorizedState.isTestingEnvironment, postbox: postbox, network: network, networkArguments: networkArguments, peerId: authorizedState.peerId, auxiliaryMethods: auxiliaryMethods, supplementary: supplementary))
|
||||
}
|
||||
@ -276,7 +276,7 @@ public func accountWithId(accountManager: AccountManager, networkArguments: Netw
|
||||
}
|
||||
}
|
||||
|
||||
return initializedNetwork(arguments: networkArguments, supplementary: supplementary, datacenterId: 2, keychain: keychain, basePath: path, testingEnvironment: beginWithTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
return initializedNetwork(accountId: id, arguments: networkArguments, supplementary: supplementary, datacenterId: 2, keychain: keychain, basePath: path, testingEnvironment: beginWithTestingEnvironment, languageCode: localizationSettings?.primaryComponent.languageCode, proxySettings: proxySettings, networkSettings: networkSettings, phoneNumber: nil)
|
||||
|> map { network -> AccountResult in
|
||||
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: beginWithTestingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection))
|
||||
}
|
||||
|
@ -424,7 +424,17 @@ public struct NetworkInitializationArguments {
|
||||
private let cloudDataContext = Atomic<CloudDataContext?>(value: nil)
|
||||
#endif
|
||||
|
||||
func initializedNetwork(arguments: NetworkInitializationArguments, supplementary: Bool, datacenterId: Int, keychain: Keychain, basePath: String, testingEnvironment: Bool, languageCode: String?, proxySettings: ProxySettings?, networkSettings: NetworkSettings?, phoneNumber: String?) -> Signal<Network, NoError> {
|
||||
private final class SharedContextStore {
|
||||
struct Key: Hashable {
|
||||
var accountId: AccountRecordId
|
||||
}
|
||||
|
||||
var contexts: [Key: MTContext] = [:]
|
||||
}
|
||||
|
||||
private let sharedContexts = Atomic<SharedContextStore>(value: SharedContextStore())
|
||||
|
||||
func initializedNetwork(accountId: AccountRecordId, arguments: NetworkInitializationArguments, supplementary: Bool, datacenterId: Int, keychain: Keychain, basePath: String, testingEnvironment: Bool, languageCode: String?, proxySettings: ProxySettings?, networkSettings: NetworkSettings?, phoneNumber: String?) -> Signal<Network, NoError> {
|
||||
return Signal { subscriber in
|
||||
let queue = Queue()
|
||||
queue.async {
|
||||
@ -464,7 +474,22 @@ func initializedNetwork(arguments: NetworkInitializationArguments, supplementary
|
||||
}
|
||||
}
|
||||
|
||||
let context = MTContext(serialization: serialization, encryptionProvider: arguments.encryptionProvider, apiEnvironment: apiEnvironment, isTestingEnvironment: testingEnvironment, useTempAuthKeys: false)!
|
||||
var contextValue: MTContext?
|
||||
sharedContexts.with { store in
|
||||
let key = SharedContextStore.Key(accountId: accountId)
|
||||
|
||||
let context: MTContext
|
||||
if let current = store.contexts[key] {
|
||||
context = current
|
||||
context.updateApiEnvironment({ _ in return apiEnvironment})
|
||||
} else {
|
||||
context = MTContext(serialization: serialization, encryptionProvider: arguments.encryptionProvider, apiEnvironment: apiEnvironment, isTestingEnvironment: testingEnvironment, useTempAuthKeys: true)!
|
||||
store.contexts[key] = context
|
||||
}
|
||||
contextValue = context
|
||||
}
|
||||
|
||||
let context = contextValue!
|
||||
|
||||
let seedAddressList: [Int: [String]]
|
||||
|
||||
|
@ -34,12 +34,18 @@ private func inputSecretChat(postbox: Postbox, peerId: PeerId) -> Signal<Api.Inp
|
||||
|> take(1)
|
||||
}
|
||||
|
||||
private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(Int32, Int32), PeerReadStateValidationError> {
|
||||
private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(Int32, Int32)?, PeerReadStateValidationError> {
|
||||
return inputPeer(postbox: postbox, peerId: peerId)
|
||||
|> mapToSignal { inputPeer -> Signal<(Int32, Int32), PeerReadStateValidationError> in
|
||||
|> mapToSignal { inputPeer -> Signal<(Int32, Int32)?, PeerReadStateValidationError> in
|
||||
return network.request(Api.functions.messages.getHistory(peer: inputPeer, offsetId: Int32.max, offsetDate: Int32.max, addOffset: 0, limit: 1, maxId: Int32.max, minId: 1, hash: 0))
|
||||
|> retryRequest
|
||||
|> mapToSignalPromotingError { result -> Signal<(Int32, Int32), PeerReadStateValidationError> in
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.messages.Messages?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignalPromotingError { result -> Signal<(Int32, Int32)?, PeerReadStateValidationError> in
|
||||
guard let result = result else {
|
||||
return .single(nil)
|
||||
}
|
||||
let apiMessages: [Api.Message]
|
||||
switch result {
|
||||
case let .channelMessages(_, _, _, messages, _, _):
|
||||
@ -60,14 +66,18 @@ private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId
|
||||
}
|
||||
}
|
||||
|
||||
private func dialogReadState(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> {
|
||||
private func dialogReadState(network: Network, postbox: Postbox, peerId: PeerId) -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> {
|
||||
return dialogTopMessage(network: network, postbox: postbox, peerId: peerId)
|
||||
|> mapToSignal { topMessage -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> in
|
||||
|> mapToSignal { topMessage -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> in
|
||||
guard let _ = topMessage else {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
return inputPeer(postbox: postbox, peerId: peerId)
|
||||
|> mapToSignal { inputPeer -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> in
|
||||
|> mapToSignal { inputPeer -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> in
|
||||
return network.request(Api.functions.messages.getPeerDialogs(peers: [.inputDialogPeer(peer: inputPeer)]))
|
||||
|> retryRequest
|
||||
|> mapToSignalPromotingError { result -> Signal<(PeerReadState, PeerReadStateMarker), PeerReadStateValidationError> in
|
||||
|> mapToSignalPromotingError { result -> Signal<(PeerReadState, PeerReadStateMarker)?, PeerReadStateValidationError> in
|
||||
switch result {
|
||||
case let .peerDialogs(dialogs, _, _, _, state):
|
||||
if let dialog = dialogs.filter({ $0.peerId == peerId }).first {
|
||||
@ -150,10 +160,16 @@ enum PeerReadStateValidationError {
|
||||
|
||||
private func validatePeerReadState(network: Network, postbox: Postbox, stateManager: AccountStateManager, peerId: PeerId) -> Signal<Never, PeerReadStateValidationError> {
|
||||
let readStateWithInitialState = dialogReadState(network: network, postbox: postbox, peerId: peerId)
|
||||
|> map { ($0.0, $0.1) }
|
||||
|
||||
let maybeAppliedReadState = readStateWithInitialState
|
||||
|> mapToSignal { (readState, finalMarker) -> Signal<Never, PeerReadStateValidationError> in
|
||||
|> mapToSignal { data -> Signal<Never, PeerReadStateValidationError> in
|
||||
guard let (readState, _) = data else {
|
||||
return postbox.transaction { transaction -> Void in
|
||||
transaction.confirmSynchronizedIncomingReadState(peerId)
|
||||
}
|
||||
|> castError(PeerReadStateValidationError.self)
|
||||
|> ignoreValues
|
||||
}
|
||||
return stateManager.addCustomOperation(postbox.transaction { transaction -> PeerReadStateValidationError? in
|
||||
if let currentReadState = transaction.getCombinedPeerReadState(peerId) {
|
||||
loop: for (namespace, currentState) in currentReadState.states {
|
||||
|
@ -27,7 +27,7 @@ private final class UnauthorizedUpdateMessageService: NSObject, MTMessageService
|
||||
self.pipe.putNext(updates)
|
||||
}
|
||||
|
||||
func mtProto(_ mtProto: MTProto!, receivedMessage message: MTIncomingMessage!) {
|
||||
func mtProto(_ mtProto: MTProto!, receivedMessage message: MTIncomingMessage!, authInfoSelector: MTDatacenterAuthInfoSelector) {
|
||||
if let updates = (message.body as? BoxedMessage)?.body as? Api.Updates {
|
||||
self.addUpdates(updates)
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class UpdateMessageService: NSObject, MTMessageService {
|
||||
self.pipe.putNext(groups)
|
||||
}
|
||||
|
||||
func mtProto(_ mtProto: MTProto!, receivedMessage message: MTIncomingMessage!) {
|
||||
func mtProto(_ mtProto: MTProto!, receivedMessage message: MTIncomingMessage!, authInfoSelector: MTDatacenterAuthInfoSelector) {
|
||||
if let updates = (message.body as? BoxedMessage)?.body as? Api.Updates {
|
||||
self.addUpdates(updates)
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ private func accountInfo(account: Account) -> Signal<StoredAccountInfo, NoError>
|
||||
var datacenters: [Int32: AccountDatacenterInfo] = [:]
|
||||
for nId in context.knownDatacenterIds() {
|
||||
if let id = nId as? Int {
|
||||
if let authInfo = context.authInfoForDatacenter(withId: id), let authKey = authInfo.authKey {
|
||||
if let authInfo = context.authInfoForDatacenter(withId: id, selector: .persistent), let authKey = authInfo.authKey {
|
||||
let transportScheme = context.chooseTransportSchemeForConnection(toDatacenterId: id, schemes: context.transportSchemesForDatacenter(withId: id, media: true, enforceMedia: false, isProxy: false))
|
||||
var addressList: [AccountDatacenterAddress] = []
|
||||
if let transportScheme = transportScheme, let address = transportScheme.address, let host = address.host {
|
||||
|
Loading…
x
Reference in New Issue
Block a user