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, strong, readonly) MTApiEnvironment *apiEnvironment;
@property (nonatomic, readonly) bool isTestingEnvironment; @property (nonatomic, readonly) bool isTestingEnvironment;
@property (nonatomic, readonly) bool useTempAuthKeys; @property (nonatomic, readonly) bool useTempAuthKeys;
@property (nonatomic, readonly) int32_t tempKeyExpiration;
+ (int32_t)fixedTimeDifference; + (int32_t)fixedTimeDifference;
+ (void)setFixedTimeDifference:(int32_t)fixedTimeDifference; + (void)setFixedTimeDifference:(int32_t)fixedTimeDifference;

View File

@ -4,23 +4,12 @@
@class MTContext; @class MTContext;
@class MTDatacenterAuthAction;
@protocol MTDatacenterAuthActionDelegate <NSObject>
- (void)datacenterAuthActionCompleted:(MTDatacenterAuthAction *)action;
@end
@interface MTDatacenterAuthAction : NSObject @interface MTDatacenterAuthAction : NSObject
@property (nonatomic, readonly) bool tempAuth; - (instancetype)initWithAuthKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector isCdn:(bool)isCdn completion:(void (^)(MTDatacenterAuthAction *, bool))completion;
@property (nonatomic, weak) id<MTDatacenterAuthActionDelegate> delegate;
@property (nonatomic, copy) void (^completedWithResult)(bool);
- (instancetype)initWithTempAuth:(bool)tempAuth authKeyInfoSelector:(MTDatacenterAuthInfoSelector)authKeyInfoSelector bindKey:(MTDatacenterAuthKey *)bindKey; - (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId;
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId isCdn:(bool)isCdn;
- (void)cancel; - (void)cancel;
@end @end

View File

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

View File

@ -71,4 +71,6 @@
- (void)_messageResendRequestFailed:(int64_t)messageId; - (void)_messageResendRequestFailed:(int64_t)messageId;
+ (NSData *)_manuallyEncryptedMessage:(NSData *)preparedData messageId:(int64_t)messageId authKey:(MTDatacenterAuthKey *)authKey;
@end @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]); return parseAuthInfoMapKey([key longLongValue]);
} }
@interface MTContext () <MTDiscoverDatacenterAddressActionDelegate, MTDatacenterAuthActionDelegate, MTDatacenterTransferAuthActionDelegate> @interface MTContext () <MTDiscoverDatacenterAddressActionDelegate, MTDatacenterTransferAuthActionDelegate>
{ {
int64_t _uniqueId; int64_t _uniqueId;
@ -165,8 +165,7 @@ static MTDatacenterAuthInfoMapKeyStruct parseAuthInfoMapKeyInteger(NSNumber *key
MTSignal *_discoverBackupAddressListSignal; MTSignal *_discoverBackupAddressListSignal;
NSMutableDictionary *_discoverDatacenterAddressActions; NSMutableDictionary *_discoverDatacenterAddressActions;
NSMutableDictionary *_datacenterAuthActions; NSMutableDictionary<NSNumber *, MTDatacenterAuthAction *> *_datacenterAuthActions;
NSMutableDictionary *_datacenterTempAuthActions;
NSMutableDictionary *_datacenterTransferAuthActions; NSMutableDictionary *_datacenterTransferAuthActions;
NSMutableDictionary<NSNumber *, NSNumber *> *_datacenterCheckKeyRemovedActionTimestamps; NSMutableDictionary<NSNumber *, NSNumber *> *_datacenterCheckKeyRemovedActionTimestamps;
@ -228,6 +227,11 @@ static int32_t fixedTimeDifferenceValue = 0;
_apiEnvironment = apiEnvironment; _apiEnvironment = apiEnvironment;
_isTestingEnvironment = isTestingEnvironment; _isTestingEnvironment = isTestingEnvironment;
_useTempAuthKeys = useTempAuthKeys; _useTempAuthKeys = useTempAuthKeys;
#if DEBUG
_tempKeyExpiration = 1 * 60 * 60;
#else
_tempKeyExpiration = 1 * 60 * 60;
#endif
_datacenterSeedAddressSetById = [[NSMutableDictionary alloc] init]; _datacenterSeedAddressSetById = [[NSMutableDictionary alloc] init];
@ -245,7 +249,6 @@ static int32_t fixedTimeDifferenceValue = 0;
_discoverDatacenterAddressActions = [[NSMutableDictionary alloc] init]; _discoverDatacenterAddressActions = [[NSMutableDictionary alloc] init];
_datacenterAuthActions = [[NSMutableDictionary alloc] init]; _datacenterAuthActions = [[NSMutableDictionary alloc] init];
_datacenterTempAuthActions = [[NSMutableDictionary alloc] init];
_datacenterTransferAuthActions = [[NSMutableDictionary alloc] init]; _datacenterTransferAuthActions = [[NSMutableDictionary alloc] init];
_datacenterCheckKeyRemovedActionTimestamps = [[NSMutableDictionary alloc] init]; _datacenterCheckKeyRemovedActionTimestamps = [[NSMutableDictionary alloc] init];
_datacenterCheckKeyRemovedActions = [[NSMutableDictionary alloc] init]; _datacenterCheckKeyRemovedActions = [[NSMutableDictionary alloc] init];
@ -285,9 +288,6 @@ static int32_t fixedTimeDifferenceValue = 0;
NSDictionary *datacenterAuthActions = _datacenterAuthActions; NSDictionary *datacenterAuthActions = _datacenterAuthActions;
_datacenterAuthActions = nil; _datacenterAuthActions = nil;
NSDictionary *datacenterTempAuthActions = _datacenterTempAuthActions;
_datacenterTempAuthActions = nil;
NSDictionary *discoverDatacenterAddressActions = _discoverDatacenterAddressActions; NSDictionary *discoverDatacenterAddressActions = _discoverDatacenterAddressActions;
_discoverDatacenterAddressActions = nil; _discoverDatacenterAddressActions = nil;
@ -311,17 +311,9 @@ static int32_t fixedTimeDifferenceValue = 0;
[action cancel]; [action cancel];
} }
for (NSNumber *nDatacenterId in datacenterAuthActions) for (NSNumber *key in datacenterAuthActions)
{ {
MTDatacenterAuthAction *action = datacenterAuthActions[nDatacenterId]; MTDatacenterAuthAction *action = datacenterAuthActions[key];
action.delegate = nil;
[action cancel];
}
for (NSNumber *nDatacenterId in datacenterTempAuthActions)
{
MTDatacenterAuthAction *action = datacenterTempAuthActions[nDatacenterId];
action.delegate = nil;
[action cancel]; [action cancel];
} }
@ -387,6 +379,14 @@ static int32_t fixedTimeDifferenceValue = 0;
NSDictionary *datacenterAuthInfoById = [keychain objectForKey:@"datacenterAuthInfoById" group:@"persistent"]; NSDictionary *datacenterAuthInfoById = [keychain objectForKey:@"datacenterAuthInfoById" group:@"persistent"];
if (datacenterAuthInfoById != nil) { if (datacenterAuthInfoById != nil) {
_datacenterAuthInfoById = [[NSMutableDictionary alloc] initWithDictionary:datacenterAuthInfoById]; _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"]; NSDictionary *datacenterPublicKeysById = [keychain objectForKey:@"datacenterPublicKeysById" group:@"ephemeral"];
@ -617,6 +617,8 @@ static int32_t fixedTimeDifferenceValue = 0;
{ {
NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector); NSNumber *infoKey = authInfoMapIntegerKey((int32_t)datacenterId, selector);
bool wasNil = _datacenterAuthInfoById[infoKey] == nil;
if (authInfo != nil) { if (authInfo != nil) {
_datacenterAuthInfoById[infoKey] = authInfo; _datacenterAuthInfoById[infoKey] = authInfo;
} else { } else {
@ -627,7 +629,7 @@ static int32_t fixedTimeDifferenceValue = 0;
} }
if (MTLogEnabled()) { 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"]; [_keychain setObject:_datacenterAuthInfoById forKey:@"datacenterAuthInfoById" group:@"persistent"];
@ -639,6 +641,15 @@ static int32_t fixedTimeDifferenceValue = 0;
if ([listener respondsToSelector:@selector(contextDatacenterAuthInfoUpdated:datacenterId:authInfo:selector:)]) if ([listener respondsToSelector:@selector(contextDatacenterAuthInfoUpdated:datacenterId:authInfo:selector:)])
[listener contextDatacenterAuthInfoUpdated:self datacenterId:datacenterId authInfo:authInfo selector: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:^ [[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]; __weak MTContext *weakSelf = self;
authAction.delegate = self; MTDatacenterAuthAction *authAction = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:selector isCdn:isCdn completion:^(MTDatacenterAuthAction *action, __unused bool success) {
_datacenterAuthActions[@(datacenterId)] = authAction; [[MTContext contextQueue] dispatchOnQueue:^{
[authAction execute:self datacenterId:datacenterId isCdn:isCdn]; __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;
}
}
}];
}];
_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; break;
} }
} default: {
} else { [authAction execute:self datacenterId:datacenterId];
for (NSNumber *nDatacenterId in _datacenterAuthActions) {
if (_datacenterAuthActions[nDatacenterId] == action) {
[_datacenterAuthActions removeObjectForKey:nDatacenterId];
break; break;
} }
} }
@ -1395,7 +1413,7 @@ static int32_t fixedTimeDifferenceValue = 0;
_datacenterCheckKeyRemovedActionTimestamps[@(datacenterId)] = currentTimestamp; _datacenterCheckKeyRemovedActionTimestamps[@(datacenterId)] = currentTimestamp;
[_datacenterCheckKeyRemovedActions[@(datacenterId)] dispose]; [_datacenterCheckKeyRemovedActions[@(datacenterId)] dispose];
__weak MTContext *weakSelf = self; __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:^{ [[MTContext contextQueue] dispatchOnQueue:^{
__strong MTContext *strongSelf = weakSelf; __strong MTContext *strongSelf = weakSelf;
if (strongSelf == nil) { if (strongSelf == nil) {

View File

@ -12,13 +12,15 @@
#import <MtProtoKit/MTSignal.h> #import <MtProtoKit/MTSignal.h>
#import <MtProtoKit/MTDatacenterAuthMessageService.h> #import <MtProtoKit/MTDatacenterAuthMessageService.h>
#import <MtProtoKit/MTRequestMessageService.h> #import <MtProtoKit/MTRequestMessageService.h>
#import <MtProtoKit/MTBindKeyMessageService.h>
#import "MTBuffer.h" #import "MTBuffer.h"
@interface MTDatacenterAuthAction () <MTDatacenterAuthMessageServiceDelegate> @interface MTDatacenterAuthAction () <MTDatacenterAuthMessageServiceDelegate>
{ {
void (^_completion)(MTDatacenterAuthAction *, bool);
bool _isCdn; bool _isCdn;
MTDatacenterAuthInfoSelector _authKeyInfoSelector; MTDatacenterAuthInfoSelector _authKeyInfoSelector;
MTDatacenterAuthKey *_bindKey;
NSInteger _datacenterId; NSInteger _datacenterId;
__weak MTContext *_context; __weak MTContext *_context;
@ -26,42 +28,36 @@
bool _awaitingAddresSetUpdate; bool _awaitingAddresSetUpdate;
MTProto *_authMtProto; MTProto *_authMtProto;
MTProto *_bindMtProto; MTProto *_bindMtProto;
MTMetaDisposable *_verifyDisposable;
} }
@end @end
@implementation MTDatacenterAuthAction @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]; self = [super init];
if (self != nil) { if (self != nil) {
_tempAuth = tempAuth;
_authKeyInfoSelector = authKeyInfoSelector; _authKeyInfoSelector = authKeyInfoSelector;
_bindKey = bindKey; _isCdn = isCdn;
_verifyDisposable = [[MTMetaDisposable alloc] init]; _completion = [completion copy];
} }
return self; return self;
} }
- (void)dealloc - (void)dealloc {
{
[self cleanup]; [self cleanup];
} }
- (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId isCdn:(bool)isCdn - (void)execute:(MTContext *)context datacenterId:(NSInteger)datacenterId {
{
_datacenterId = datacenterId; _datacenterId = datacenterId;
_context = context; _context = context;
_isCdn = isCdn;
if (_datacenterId != 0 && context != nil) if (_datacenterId != 0 && context != nil)
{ {
bool alreadyCompleted = false; bool alreadyCompleted = false;
MTDatacenterAuthInfo *currentAuthInfo = [context authInfoForDatacenterWithId:_datacenterId selector:_authKeyInfoSelector]; MTDatacenterAuthInfo *currentAuthInfo = [context authInfoForDatacenterWithId:_datacenterId selector:_authKeyInfoSelector];
if (currentAuthInfo != nil && _bindKey == nil) { if (currentAuthInfo != nil) {
alreadyCompleted = true; alreadyCompleted = true;
} }
@ -69,23 +65,24 @@
[self complete]; [self complete];
} else { } else {
_authMtProto = [[MTProto alloc] initWithContext:context datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0]; _authMtProto = [[MTProto alloc] initWithContext:context datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0];
_authMtProto.cdn = isCdn; _authMtProto.cdn = _isCdn;
_authMtProto.useUnauthorizedMode = true; _authMtProto.useUnauthorizedMode = true;
if (_tempAuth) { bool tempAuth = false;
switch (_authKeyInfoSelector) { switch (_authKeyInfoSelector) {
case MTDatacenterAuthInfoSelectorEphemeralMain: case MTDatacenterAuthInfoSelectorEphemeralMain:
_authMtProto.media = false; tempAuth = true;
break; _authMtProto.media = false;
case MTDatacenterAuthInfoSelectorEphemeralMedia: break;
_authMtProto.media = true; case MTDatacenterAuthInfoSelectorEphemeralMedia:
_authMtProto.enforceMedia = true; tempAuth = true;
break; _authMtProto.media = true;
default: _authMtProto.enforceMedia = true;
break; break;
} default:
break;
} }
MTDatacenterAuthMessageService *authService = [[MTDatacenterAuthMessageService alloc] initWithContext:context tempAuth:_tempAuth]; MTDatacenterAuthMessageService *authService = [[MTDatacenterAuthMessageService alloc] initWithContext:context tempAuth:tempAuth];
authService.delegate = self; authService.delegate = self;
[_authMtProto addMessageService:authService]; [_authMtProto addMessageService:authService];
} }
@ -99,44 +96,71 @@
} }
- (void)completeWithAuthKey:(MTDatacenterAuthKey *)authKey timestamp:(int64_t)timestamp { - (void)completeWithAuthKey:(MTDatacenterAuthKey *)authKey timestamp:(int64_t)timestamp {
if (_tempAuth) { if (MTLogEnabled()) {
MTContext *mainContext = _context; MTLog(@"[MTDatacenterAuthAction#%p@%p: completeWithAuthKey %lld selector %d]", self, _context, authKey.authKeyId, _authKeyInfoSelector);
if (mainContext != nil) { }
if (_bindKey != nil) {
_bindMtProto = [[MTProto alloc] initWithContext:mainContext datacenterId:_datacenterId usageCalculationInfo:nil requiredAuthToken:nil authTokenMasterDatacenterId:0]; switch (_authKeyInfoSelector) {
_bindMtProto.cdn = false; case MTDatacenterAuthInfoSelectorPersistent: {
_bindMtProto.useUnauthorizedMode = false; 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];
_bindMtProto.useTempAuthKeys = true;
__weak MTDatacenterAuthAction *weakSelf = self; MTContext *context = _context;
_bindMtProto.tempAuthKeyBindingResultUpdated = ^(bool success) { [context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector];
__strong MTDatacenterAuthAction *strongSelf = weakSelf; [self complete];
if (strongSelf == nil) { }
return; 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) { __weak MTDatacenterAuthAction *weakSelf = self;
strongSelf->_completedWithResult(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) {
_bindMtProto.useExplicitAuthKey = authKey; return;
[_bindMtProto resume]; }
} else { [strongSelf->_bindMtProto stop];
MTContext *context = _context;
[context performBatchUpdates:^{ if (success) {
MTDatacenterAuthInfo *authInfo = [context authInfoForDatacenterWithId:_datacenterId selector:_authKeyInfoSelector]; 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];
if (authInfo != nil) {
[context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector]; [strongSelf->_context updateAuthInfoForDatacenterWithId:strongSelf->_datacenterId authInfo:authInfo selector:strongSelf->_authKeyInfoSelector];
}
}]; [strongSelf complete];
[self complete]; } else {
[strongSelf fail];
}
}]];
[_bindMtProto resume];
}
} }
} }
} else { break;
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];
default:
MTContext *context = _context; assert(false);
[context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:authInfo selector:_authKeyInfoSelector]; break;
[self complete];
} }
} }
@ -147,7 +171,10 @@
[authMtProto stop]; [authMtProto stop];
[_verifyDisposable dispose]; MTProto *bindMtProto = _bindMtProto;
_bindMtProto = nil;
[bindMtProto stop];
} }
- (void)cancel - (void)cancel
@ -156,18 +183,17 @@
[self fail]; [self fail];
} }
- (void)complete - (void)complete {
{ if (_completion) {
id<MTDatacenterAuthActionDelegate> delegate = _delegate; _completion(self, true);
if ([delegate respondsToSelector:@selector(datacenterAuthActionCompleted:)]) }
[delegate datacenterAuthActionCompleted:self];
} }
- (void)fail - (void)fail
{ {
id<MTDatacenterAuthActionDelegate> delegate = _delegate; if (_completion) {
if ([delegate respondsToSelector:@selector(datacenterAuthActionCompleted:)]) _completion(self, false);
[delegate datacenterAuthActionCompleted:self]; }
} }
@end @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) if (_currentStageTransactionId == nil)
{ {
@ -389,7 +389,7 @@ typedef enum {
[innerDataBuffer appendBytes:_nonce.bytes length:_nonce.length]; [innerDataBuffer appendBytes:_nonce.bytes length:_nonce.length];
[innerDataBuffer appendBytes:_serverNonce.bytes length:_serverNonce.length]; [innerDataBuffer appendBytes:_serverNonce.bytes length:_serverNonce.length];
[innerDataBuffer appendBytes:_newNonce.bytes length:_newNonce.length]; [innerDataBuffer appendBytes:_newNonce.bytes length:_newNonce.length];
[innerDataBuffer appendInt32:60 * 60 * 32]; [innerDataBuffer appendInt32:mtProto.context.tempKeyExpiration];
NSData *innerDataBytes = innerDataBuffer.data; NSData *innerDataBytes = innerDataBuffer.data;

View File

@ -249,12 +249,11 @@
MTMetaDisposable *disposable = [[MTMetaDisposable alloc] init]; MTMetaDisposable *disposable = [[MTMetaDisposable alloc] init];
[[MTContext contextQueue] dispatchOnQueue:^{ [[MTContext contextQueue] dispatchOnQueue:^{
MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithTempAuth:true authKeyInfoSelector:MTDatacenterAuthInfoSelectorEphemeralMain bindKey:authKey]; MTDatacenterAuthAction *action = [[MTDatacenterAuthAction alloc] initWithAuthKeyInfoSelector:MTDatacenterAuthInfoSelectorEphemeralMain isCdn:false completion:^(__unused MTDatacenterAuthAction *action, bool success) {
action.completedWithResult = ^(bool success) {
[subscriber putNext:@(!success)]; [subscriber putNext:@(!success)];
[subscriber putCompletion]; [subscriber putCompletion];
}; }];
[action execute:context datacenterId:datacenterId isCdn:false]; [action execute:context datacenterId:datacenterId];
[disposable setDisposable:[[MTBlockDisposable alloc] initWithBlock:^{ [disposable setDisposable:[[MTBlockDisposable alloc] initWithBlock:^{
[action cancel]; [action cancel];

View File

@ -828,42 +828,60 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
} }
- (MTDatacenterAuthKey *)getAuthKeyForCurrentScheme:(MTTransportScheme *)scheme createIfNeeded:(bool)createIfNeeded authInfoSelector:(MTDatacenterAuthInfoSelector *)authInfoSelector { - (MTDatacenterAuthKey *)getAuthKeyForCurrentScheme:(MTTransportScheme *)scheme createIfNeeded:(bool)createIfNeeded authInfoSelector:(MTDatacenterAuthInfoSelector *)authInfoSelector {
MTDatacenterAuthInfoSelector selector = MTDatacenterAuthInfoSelectorPersistent; if (_useExplicitAuthKey) {
MTDatacenterAuthInfoSelector selector = MTDatacenterAuthInfoSelectorEphemeralMain;
if (_cdn) { if (authInfoSelector != nil) {
selector = MTDatacenterAuthInfoSelectorPersistent; *authInfoSelector = selector;
} else {
if (_useTempAuthKeys) {
if (scheme.address.preferForMedia) {
selector = MTDatacenterAuthInfoSelectorEphemeralMedia;
} else {
selector = MTDatacenterAuthInfoSelectorEphemeralMain;
}
} else {
selector = MTDatacenterAuthInfoSelectorPersistent;
} }
}
if (_validAuthInfo != nil && _validAuthInfo.selector == selector) {
if (authInfoSelector != nil) { return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
*authInfoSelector = selector; }
}
MTDatacenterAuthInfo *authInfo = [[MTDatacenterAuthInfo alloc] initWithAuthKey:_useExplicitAuthKey.authKey authKeyId:_useExplicitAuthKey.authKeyId saltSet:@[[[MTDatacenterSaltInfo alloc] initWithSalt:0 firstValidMessageId:0 lastValidMessageId:0]] authKeyAttributes:nil];
if (_validAuthInfo != nil && _validAuthInfo.selector == selector) {
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:authInfo selector:selector];
return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false]; return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
} else { } else {
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:selector]; MTDatacenterAuthInfoSelector selector = MTDatacenterAuthInfoSelectorPersistent;
if (authInfo != nil) {
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:authInfo selector:selector]; 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]; return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
} else { } else {
[_context performBatchUpdates:^{ MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:selector];
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:nil selector:selector]; if (authInfo != nil) {
[_context authInfoForDatacenterWithIdRequired:_datacenterId isCdn:_cdn selector:selector]; _validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:authInfo selector:selector];
}]; return [[MTDatacenterAuthKey alloc] initWithAuthKey:_validAuthInfo.authInfo.authKey authKeyId:_validAuthInfo.authInfo.authKeyId notBound:false];
_mtState |= MTProtoStateAwaitingDatacenterAuthorization; } else {
_awaitingAuthInfoForSelector = @(selector); if (createIfNeeded) {
[_context performBatchUpdates:^{
return nil; [_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]; NSMutableArray *messageServiceTransactions = [[NSMutableArray alloc] init];
for (id<MTMessageService> messageService in _messageServices) 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) if (messageTransaction != nil)
{ {
for (MTOutgoingMessage *message in messageTransaction.messagePayload) for (MTOutgoingMessage *message in messageTransaction.messagePayload)
@ -1496,7 +1514,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
return messageData; return messageData;
} }
- (NSData *)paddedDataV1:(NSData *)data { + (NSData *)paddedDataV1:(NSData *)data {
NSMutableData *padded = [[NSMutableData alloc] initWithData:data]; NSMutableData *padded = [[NSMutableData alloc] initWithData:data];
uint8_t randomBytes[128]; uint8_t randomBytes[128];
arc4random_buf(randomBytes, 128); arc4random_buf(randomBytes, 128);
@ -1543,7 +1561,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
return padded; 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]; MTOutputStream *decryptedOs = [[MTOutputStream alloc] init];
int64_t random1 = 0; int64_t random1 = 0;
@ -1559,7 +1577,7 @@ static const NSUInteger MTMaxUnacknowledgedMessageCount = 64;
[decryptedOs writeInt32:(int32_t)preparedData.length]; [decryptedOs writeInt32:(int32_t)preparedData.length];
[decryptedOs writeData:preparedData]; [decryptedOs writeData:preparedData];
NSData *decryptedData = [self paddedDataV1:[decryptedOs currentBytes]]; NSData *decryptedData = [MTProto paddedDataV1:[decryptedOs currentBytes]];
NSData *messageKeyFull = MTSubdataSha1(decryptedData, 0, 32 + preparedData.length); NSData *messageKeyFull = MTSubdataSha1(decryptedData, 0, 32 + preparedData.length);
NSData *messageKey = [[NSData alloc] initWithBytes:(((int8_t *)messageKeyFull.bytes) + messageKeyFull.length - 16) length:16]; 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; MTDatacenterAuthInfoSelector authInfoSelector;
[self getAuthKeyForCurrentScheme:scheme createIfNeeded:false authInfoSelector:&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) { if (_useExplicitAuthKey != nil) {
} else if (_cdn) { } else if (_cdn) {
_validAuthInfo = nil; _validAuthInfo = nil;
@ -2047,7 +2069,23 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
_mtState |= MTProtoStateAwaitingDatacenterAuthorization; _mtState |= MTProtoStateAwaitingDatacenterAuthorization;
_awaitingAuthInfoForSelector = @(authInfoSelector); _awaitingAuthInfoForSelector = @(authInfoSelector);
} else { } 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) { } else if (_awaitingAuthInfoForSelector != nil) {
if ([_awaitingAuthInfoForSelector intValue] != selector) { if ([_awaitingAuthInfoForSelector intValue] != selector) {
return; return;
} else if (authInfo != nil) {
_awaitingAuthInfoForSelector = nil;
} }
} else { } else {
return; return;
@ -2566,14 +2606,21 @@ static NSString *dumpHexString(NSData *data, int maxLength) {
if (saltList != nil) if (saltList != nil)
{ {
MTDatacenterAuthInfo *authInfo = [_context authInfoForDatacenterWithId:_datacenterId selector:authInfoSelector]; if (_useExplicitAuthKey) {
if (authInfo != nil)
{
MTDatacenterAuthInfo *updatedAuthInfo = [authInfo mergeSaltSet:saltList forTimestamp:[_context globalTime]];
[_context updateAuthInfoForDatacenterWithId:_datacenterId authInfo:updatedAuthInfo selector:authInfoSelector];
if (_validAuthInfo != nil && _validAuthInfo.selector == authInfoSelector) { if (_validAuthInfo != nil && _validAuthInfo.selector == authInfoSelector) {
MTDatacenterAuthInfo *updatedAuthInfo = [_validAuthInfo.authInfo mergeSaltSet:saltList forTimestamp:[_context globalTime]];
_validAuthInfo = [[MTProtoValidAuthInfo alloc] initWithAuthInfo:updatedAuthInfo selector:authInfoSelector]; _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; return currentData;
} }
- (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector - (MTMessageTransaction *)mtProtoMessageTransaction:(MTProto *)mtProto authInfoSelector:(MTDatacenterAuthInfoSelector)authInfoSelector sessionInfo:(MTSessionInfo *)sessionInfo
{ {
NSMutableArray *messages = nil; NSMutableArray *messages = nil;
NSMutableDictionary *requestInternalIdToMessageInternalId = nil; NSMutableDictionary *requestInternalIdToMessageInternalId = nil;

View File

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

View File

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

View File

@ -104,7 +104,7 @@ public class UnauthorizedAccount {
} }
for id in datacenterIds { for id in datacenterIds {
if network.context.authInfoForDatacenter(withId: id, selector: .persistent) == nil { 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() network.context.beginExplicitBackupAddressDiscovery()
@ -128,7 +128,7 @@ public class UnauthorizedAccount {
} }
} }
|> mapToSignal { (localizationSettings, proxySettings, networkSettings) -> Signal<UnauthorizedAccount, NoError> in |> 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 |> 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) 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()) updated.shouldBeServiceTaskMaster.set(self.shouldBeServiceTaskMaster.get())
@ -257,7 +257,7 @@ public func accountWithId(accountManager: AccountManager, networkArguments: Netw
if let accountState = accountState { if let accountState = accountState {
switch accountState { switch accountState {
case let unauthorizedState as UnauthorizedAccountState: 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 |> map { network -> AccountResult in
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: unauthorizedState.isTestingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection)) 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 return (transaction.getPeer(authorizedState.peerId) as? TelegramUser)?.phone
} }
|> mapToSignal { phoneNumber in |> 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 |> 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)) 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 |> map { network -> AccountResult in
return .unauthorized(UnauthorizedAccount(networkArguments: networkArguments, id: id, rootPath: rootPath, basePath: path, testingEnvironment: beginWithTestingEnvironment, postbox: postbox, network: network, shouldKeepAutoConnection: shouldKeepAutoConnection)) 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) private let cloudDataContext = Atomic<CloudDataContext?>(value: nil)
#endif #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 return Signal { subscriber in
let queue = Queue() let queue = Queue()
queue.async { 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]] let seedAddressList: [Int: [String]]

View File

@ -27,7 +27,7 @@ private final class UnauthorizedUpdateMessageService: NSObject, MTMessageService
self.pipe.putNext(updates) 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 { if let updates = (message.body as? BoxedMessage)?.body as? Api.Updates {
self.addUpdates(updates) self.addUpdates(updates)
} }

View File

@ -34,7 +34,7 @@ class UpdateMessageService: NSObject, MTMessageService {
self.pipe.putNext(groups) 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 { if let updates = (message.body as? BoxedMessage)?.body as? Api.Updates {
self.addUpdates(updates) self.addUpdates(updates)
} }