This commit is contained in:
Ali 2020-09-10 21:02:44 +01:00
parent 56affdf64f
commit 6d6cc6508b
18 changed files with 460 additions and 187 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 authKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector bindKey:(MTDatacenterAuthKey *)bindKey;
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId isCdn:(bool)isCdn;
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId;
- (void)cancel;
@end

View File

@ -7,6 +7,7 @@
@class MTIncomingMessage;
@class MTMessageTransaction;
@class MTApiEnvironment;
@class MTSessionInfo;
@protocol MTMessageService <NSObject>
@ -16,7 +17,7 @@
- (void)mtProtoDidAddService:(MTProto *)mtProto;
- (void)mtProtoDidRemoveService:(MTProto *)mtProto;
- (void)mtProtoPublicKeysUpdated:(MTProto *)mtProto datacenterId:(NSInteger)datacenterId publicKeys:(NSArray<NSDictionary *> *)publicKeys;
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector;
- (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 authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector;

View File

@ -71,4 +71,6 @@
- (void)_messageResendRequestFailed:(int64_t)messageId;
+ (NSData *)_manuallyEncryptedMessage:(NSData *)preparedData messageId:(int64_t)messageId authKey:(MTDatacenterAuthKey *)authKey;
@end

View 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

View File

@ -141,7 +141,7 @@ static MTDatacenterAuthInfoMapKeyStruct parseAuthInfoMapKeyInteger(NSNumber *key
return parseAuthInfoMapKey([key longLongValue]);
}
@interface MTContext () <MTDiscoverDatacenterAddressActionDelegate, MTDatacenterAuthActionDelegate, MTDatacenterTransferAuthActionDelegate>
@interface MTContext () <MTDiscoverDatacenterAddressActionDelegate, MTDatacenterTransferAuthActionDelegate>
{
int64_t _uniqueId;
@ -165,8 +165,7 @@ static MTDatacenterAuthInfoMapKeyStruct parseAuthInfoMapKeyInteger(NSNumber *key
MTSignal *_discoverBackupAddressListSignal;
NSMutableDictionary *_discoverDatacenterAddressActions;
NSMutableDictionary *_datacenterAuthActions;
NSMutableDictionary *_datacenterTempAuthActions;
NSMutableDictionary<NSNumber *, MTDatacenterAuthAction *> *_datacenterAuthActions;
NSMutableDictionary *_datacenterTransferAuthActions;
NSMutableDictionary<NSNumber *, NSNumber *> *_datacenterCheckKeyRemovedActionTimestamps;
@ -228,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];
@ -245,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];
@ -285,9 +288,6 @@ static int32_t fixedTimeDifferenceValue = 0;
NSDictionary *datacenterAuthActions = _datacenterAuthActions;
_datacenterAuthActions = nil;
NSDictionary *datacenterTempAuthActions = _datacenterTempAuthActions;
_datacenterTempAuthActions = nil;
NSDictionary *discoverDatacenterAddressActions = _discoverDatacenterAddressActions;
_discoverDatacenterAddressActions = nil;
@ -311,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];
}
@ -387,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"];
@ -617,6 +617,8 @@ static int32_t fixedTimeDifferenceValue = 0;
{
NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector);
bool wasNil = _datacenterAuthInfoById[infoKey] == nil;
if (authInfo != nil) {
_datacenterAuthInfoById[infoKey] = authInfo;
} else {
@ -627,7 +629,7 @@ static int32_t fixedTimeDifferenceValue = 0;
}
if (MTLogEnabled()) {
MTLog(@"[MTContext#%x: auth info updated for %d to %@]", (int)self, datacenterId, authInfo);
MTLog(@"[MTContext#%x: auth info updated for %d selector %d to %@]", (int)self, datacenterId, selector, authInfo);
}
[_keychain setObject:_datacenterAuthInfoById forKey:@"datacenterAuthInfoById" group:@"persistent"];
@ -639,6 +641,15 @@ static int32_t fixedTimeDifferenceValue = 0;
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];
}
}
}
}
}];
}
@ -1289,33 +1300,40 @@ static int32_t fixedTimeDifferenceValue = 0;
{
[[MTContext contextQueue] dispatchOnQueue:^
{
if (_datacenterAuthActions[@(datacenterId)] == nil)
NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector);
if (_datacenterAuthActions[infoKey] == nil)
{
MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithTempAuth:false authKeyInfoSelector:selector bindKey:nil];
authAction.delegate = self;
_datacenterAuthActions[@(datacenterId)] = authAction;
[authAction execute:self datacenterId:datacenterId isCdn:isCdn];
}
}];
}
- (void)datacenterAuthActionCompleted:(MTDatacenterAuthAction *)action
{
[[MTContext contextQueue] dispatchOnQueue:^
{
if (action.tempAuth) {
for (NSNumber *nDatacenterId in _datacenterTempAuthActions) {
if (_datacenterTempAuthActions[nDatacenterId] == action) {
[_datacenterTempAuthActions removeObjectForKey:nDatacenterId];
__weak MTContext *weakSelf = self;
MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:selector isCdn:isCdn completion:^(MTDatacenterAuthAction *action, __unused bool success) {
[[MTContext contextQueue] dispatchOnQueue:^{
__strong MTContext *strongSelf = weakSelf;
if (strongSelf == nil) {
return;
}
for (NSNumber *key in _datacenterAuthActions) {
if (_datacenterAuthActions[key] == action) {
[_datacenterAuthActions removeObjectForKey:key];
break;
}
}
}];
}];
_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;
}
}
} else {
for (NSNumber *nDatacenterId in _datacenterAuthActions) {
if (_datacenterAuthActions[nDatacenterId] == action) {
[_datacenterAuthActions removeObjectForKey:nDatacenterId];
default: {
[authAction execute:self datacenterId:datacenterId];
break;
}
}
@ -1395,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:[[MTDatacenterAuthKey alloc] initWithAuthKey:authInfo.authKey authKeyId:authInfo.authKeyId notBound:false]] 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) {

View File

@ -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;
MTDatacenterAuthInfoSelector _authKeyInfoSelector;
MTDatacenterAuthKey *_bindKey;
NSInteger _datacenterId;
__weak MTContext *_context;
@ -26,42 +28,36 @@
bool _awaitingAddresSetUpdate;
MTProto *_authMtProto;
MTProto *_bindMtProto;
MTMetaDisposable *_verifyDisposable;
}
@end
@implementation MTDatacenterAuthAction
- (instancetype)initWithTempAuth:(bool)tempAuth authKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector bindKey:(MTDatacenterAuthKey *)bindKey {
- (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn completion:(void (^)(MTDatacenterAuthAction *, bool))completion {
self = [super init];
if (self != nil) {
_tempAuth = tempAuth;
_authKeyInfoSelector = authKeyInfoSelector;
_bindKey = bindKey;
_verifyDisposable = [[MTMetaDisposable alloc] init];
_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 selector:_authKeyInfoSelector];
if (currentAuthInfo != nil && _bindKey == nil) {
if (currentAuthInfo != nil) {
alreadyCompleted = true;
}
@ -69,23 +65,24 @@
[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 (_authKeyInfoSelector) {
case MTDatacenterAuthInfoSelectorEphemeralMain:
_authMtProto.media = false;
break;
case MTDatacenterAuthInfoSelectorEphemeralMedia:
_authMtProto.media = true;
_authMtProto.enforceMedia = true;
break;
default:
break;
}
bool tempAuth = false;
switch (_authKeyInfoSelector) {
case MTDatacenterAuthInfoSelectorEphemeralMain:
tempAuth = true;
_authMtProto.media = false;
break;
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];
}
@ -99,44 +96,71 @@
}
- (void)completeWithAuthKey:(MTDatacenterAuthKey *)authKey timestamp:(int64_t)timestamp {
if (_tempAuth) {
MTContext *mainContext = _context;
if (mainContext != nil) {
if (_bindKey != nil) {
_bindMtProto = [[MTProto alloc] initWithContext:mainContext datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
_bindMtProto.cdn = false;
_bindMtProto.useUnauthorizedMode = false;
_bindMtProto.useTempAuthKeys = true;
__weak MTDatacenterAuthAction *weakSelf = self;
_bindMtProto.tempAuthKeyBindingResultUpdated = ^(bool success) {
__strong MTDatacenterAuthAction *strongSelf = weakSelf;
if (strongSelf == nil) {
return;
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) {
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;
}
[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 selector:_authKeyInfoSelector];
if (authInfo != nil) {
[context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector];
}
}];
[self complete];
__weak MTDatacenterAuthAction *weakSelf = self;
[_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 (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];
}
}
}
} 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];
MTContext *context = _context;
[context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector];
[self complete];
break;
default:
assert(false);
break;
}
}
@ -147,7 +171,10 @@
[authMtProto stop];
[_verifyDisposable dispose];
MTProto *bindMtProto = _bindMtProto;
_bindMtProto = nil;
[bindMtProto stop];
}
- (void)cancel
@ -156,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

View File

@ -222,7 +222,7 @@ typedef enum {
}
}
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
{
if (_currentStageTransactionId == nil)
{
@ -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;

View File

@ -249,12 +249,11 @@
MTMetaDisposable *disposable = [[MTMetaDisposable alloc] init];
[[MTContext contextQueue] dispatchOnQueue:^{
MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithTempAuth:true authKeyInfoSelector:MTDatacenterAuthInfoSelectorEphemeralMain 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];

View File

@ -828,42 +828,60 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
}
- (MTDatacenterAuthKey *)getAuthKeyForCurrentScheme:(MTTransportScheme *)scheme createIfNeeded:(bool)createIfNeeded authInfoSelector:(MTDatacenterAuthInfoSelector *)authInfoSelector {
MTDatacenterAuthInfoSelector selector = MTDatacenterAuthInfoSelectorPersistent;
if (_cdn) {
selector = MTDatacenterAuthInfoSelectorPersistent;
} else {
if (_useTempAuthKeys) {
if (scheme.address.preferForMedia) {
selector = MTDatacenterAuthInfoSelectorEphemeralMedia;
} else {
selector = MTDatacenterAuthInfoSelectorEphemeralMain;
}
} else {
selector = MTDatacenterAuthInfoSelectorPersistent;
if (_useExplicitAuthKey) {
MTDatacenterAuthInfoSelector selector = MTDatacenterAuthInfoSelectorEphemeralMain;
if (authInfoSelector != nil) {
*authInfoSelector = selector;
}
}
if (authInfoSelector != nil) {
*authInfoSelector = selector;
}
if (_validAuthInfo != nil && _validAuthInfo.selector == selector) {
if (_validAuthInfo != nil && _validAuthInfo.selector == selector) {
return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
}
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:_useExplicitAuthKey.authKey authKeyId:_useExplicitAuthKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:0 lastValidMessageId:0]] authKeyAttributes:nil];
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:authInfo selector:selector];
return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
} else {
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:selector];
if (authInfo != nil) {
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:authInfo selector:selector];
MTDatacenterAuthInfoSelector selector = MTDatacenterAuthInfoSelectorPersistent;
if (_cdn) {
selector = MTDatacenterAuthInfoSelectorPersistent;
} else {
if (_useTempAuthKeys) {
if (scheme.address.preferForMedia) {
selector = MTDatacenterAuthInfoSelectorEphemeralMedia;
} else {
selector = MTDatacenterAuthInfoSelectorEphemeralMain;
}
} else {
selector = MTDatacenterAuthInfoSelectorPersistent;
}
}
if (authInfoSelector != nil) {
*authInfoSelector = selector;
}
if (_validAuthInfo != nil && _validAuthInfo.selector == selector) {
return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
} else {
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:selector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:_cdn selector:selector];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(selector);
return nil;
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:selector];
if (authInfo != nil) {
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:authInfo selector:selector];
return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
} else {
if (createIfNeeded) {
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:selector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:_cdn selector:selector];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(selector);
}
return nil;
}
}
}
}
@ -924,9 +942,9 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
NSMutableArray *messageServiceTransactions = [[NSMutableArray alloc] init];
for (id<MTMessageService> messageService in _messageServices)
{
if ([messageService respondsToSelector:@selector(mtProtoMessageTransaction:authInfoSelector:)])
if ([messageService respondsToSelector:@selector(mtProtoMessageTransaction:authInfoSelector:sessionInfo:)])
{
MTMessageTransaction *messageTransaction = [messageService mtProtoMessageTransaction:self authInfoSelector:authInfoSelector];
MTMessageTransaction *messageTransaction = [messageService mtProtoMessageTransaction:self authInfoSelector:authInfoSelector sessionInfo:transactionSessionInfo];
if (messageTransaction != nil)
{
for (MTOutgoingMessage *message in messageTransaction.messagePayload)
@ -1496,7 +1514,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
return messageData;
}
- (NSData *)paddedDataV1:(NSData *)data {
+ (NSData *)paddedDataV1:(NSData *)data {
NSMutableData *padded = [[NSMutableData alloc] initWithData:data];
uint8_t randomBytes[128];
arc4random_buf(randomBytes, 128);
@ -1543,7 +1561,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
return padded;
}
- (NSData *)_manuallyEncryptedMessage:(NSData *)preparedData messageId:(int64_t)messageId authKey:(MTDatacenterAuthKey *)authKey {
+ (NSData *)_manuallyEncryptedMessage:(NSData *)preparedData messageId:(int64_t)messageId authKey:(MTDatacenterAuthKey *)authKey {
MTOutputStream *decryptedOs = [[MTOutputStream alloc] init];
int64_t random1 = 0;
@ -1559,7 +1577,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
[decryptedOs writeInt32:(int32_t)preparedData.length];
[decryptedOs writeData:preparedData];
NSData *decryptedData = [self paddedDataV1:[decryptedOs currentBytes]];
NSData *decryptedData = [MTProto paddedDataV1:[decryptedOs currentBytes]];
NSData *messageKeyFull = MTSubdataSha1(decryptedData, 0, 32 + preparedData.length);
NSData *messageKey = [[NSData alloc] initWithBytes:(((int8_t *)messageKeyFull.bytes) + messageKeyFull.length - 16) length:16];
@ -2013,6 +2031,10 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
MTDatacenterAuthInfoSelector authInfoSelector;
[self getAuthKeyForCurrentScheme:scheme createIfNeeded:false authInfoSelector:&authInfoSelector];
if (MTLogEnabled()) {
MTLog(@"[MTProto#%p@%p missing key %lld selector]", self, _context, _validAuthInfo.authInfo.authKeyId, authInfoSelector);
}
if (_useExplicitAuthKey != nil) {
} else if (_cdn) {
_validAuthInfo = nil;
@ -2047,7 +2069,23 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(authInfoSelector);
} else {
[_context checkIfLoggedOut:_datacenterId];
switch (authInfoSelector) {
case MTDatacenterAuthInfoSelectorEphemeralMain:
case MTDatacenterAuthInfoSelectorEphemeralMedia: {
_validAuthInfo = nil;
[_context performBatchUpdates:^{
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:authInfoSelector];
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:false selector:authInfoSelector];
}];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(authInfoSelector);
break;
}
default:
[_context checkIfLoggedOut:_datacenterId];
break;
}
}
}
}
@ -2497,6 +2535,8 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
} else if (_awaitingAuthInfoForSelector != nil) {
if ([_awaitingAuthInfoForSelector intValue] != selector) {
return;
} else if (authInfo != nil) {
_awaitingAuthInfoForSelector = nil;
}
} else {
return;
@ -2566,14 +2606,21 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
if (saltList != nil)
{
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:authInfoSelector];
if (authInfo != nil)
{
MTDatacenterAuthInfo *updatedAuthInfo = [authInfo mergeSaltSet:saltList forTimestamp:[_context globalTime]];
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:updatedAuthInfo selector:authInfoSelector];
if (_useExplicitAuthKey) {
if (_validAuthInfo != nil && _validAuthInfo.selector == authInfoSelector) {
MTDatacenterAuthInfo *updatedAuthInfo = [_validAuthInfo.authInfo mergeSaltSet:saltList forTimestamp:[_context globalTime]];
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:updatedAuthInfo selector:authInfoSelector];
}
} else {
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:authInfoSelector];
if (authInfo != nil)
{
MTDatacenterAuthInfo *updatedAuthInfo = [authInfo mergeSaltSet:saltList forTimestamp:[_context globalTime]];
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:updatedAuthInfo selector:authInfoSelector];
if (_validAuthInfo != nil && _validAuthInfo.selector == authInfoSelector) {
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:updatedAuthInfo selector:authInfoSelector];
}
}
}
}

View File

@ -391,7 +391,7 @@
return currentData;
}
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
{
NSMutableArray *messages = nil;
NSMutableDictionary *requestInternalIdToMessageInternalId = nil;

View File

@ -41,7 +41,7 @@
[mtProto requestTransportTransaction];
}
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
{
if (_currentRequestMessageId == 0 || _currentRequestTransactionId == nil)
{

View File

@ -45,7 +45,7 @@
[mtProto requestTransportTransaction];
}
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
{
if (_currentTransactionId == nil)
{

View File

@ -104,7 +104,7 @@ public class UnauthorizedAccount {
}
for id in datacenterIds {
if network.context.authInfoForDatacenter(withId: id, selector: .persistent) == nil {
network.context.authInfoForDatacenter(withIdRequired: id, isCdn: false, selector: .persistent)
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())
@ -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))
}

View File

@ -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]]

View File

@ -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)
}

View File

@ -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)
}