From be2ee63fd3fe3d2c17ad04ee5669c98f459ba127 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 1 May 2018 16:42:05 +0300 Subject: [PATCH] no message --- MTBackupAddressSignals.h | 2 +- MTBackupAddressSignals.m | 126 ++++++++++++------------- MTProtoKit/MTEncryption.h | 5 +- MTProtoKit/MTEncryption.m | 176 +++++++++++++++++++++++++++-------- MTProtoKit/MTTcpConnection.m | 12 +-- 5 files changed, 205 insertions(+), 116 deletions(-) diff --git a/MTBackupAddressSignals.h b/MTBackupAddressSignals.h index 35045bb938..2a000cf464 100644 --- a/MTBackupAddressSignals.h +++ b/MTBackupAddressSignals.h @@ -5,6 +5,6 @@ @interface MTBackupAddressSignals : NSObject -+ (MTSignal *)fetchBackupIps:(bool)isTestingEnvironment currentContext:(MTContext *)currentContext; ++ (MTSignal * _Nonnull)fetchBackupIps:(bool)isTestingEnvironment currentContext:(MTContext * _Nonnull)currentContext phoneNumber:(NSString * _Nullable)phoneNumber; @end diff --git a/MTBackupAddressSignals.m b/MTBackupAddressSignals.m index 64181f6a78..4ecff613cf 100644 --- a/MTBackupAddressSignals.m +++ b/MTBackupAddressSignals.m @@ -46,36 +46,16 @@ @implementation MTBackupAddressSignals -+ (MTSignal *)fetchBackupIpsGoogle:(bool)isTesting { - NSDictionary *headers = @{@"Host": @"dns-telegram.appspot.com"}; - - return [[[MTHttpRequestOperation dataForHttpUrl:[NSURL URLWithString:isTesting ? @"https://google.com/test/" : @"https://google.com/"] headers:headers] mapToSignal:^MTSignal *(NSData *data) { - NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - text = [text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]]; - NSData *result = [[NSData alloc] initWithBase64EncodedString:text options:NSDataBase64DecodingIgnoreUnknownCharacters]; - NSMutableData *finalData = [[NSMutableData alloc] initWithData:result]; - [finalData setLength:256]; - MTBackupDatacenterData *datacenterData = MTIPDataDecode(finalData); - if (datacenterData != nil) { - return [MTSignal single:datacenterData]; - } else { - return [MTSignal complete]; - }; - }] catch:^MTSignal *(__unused id error) { - return [MTSignal complete]; - }]; -} - -+ (MTSignal *)fetchBackupIpsAzure:(bool)isTesting { ++ (MTSignal *)fetchBackupIpsAzure:(bool)isTesting phoneNumber:(NSString *)phoneNumber { NSDictionary *headers = @{@"Host": @"tcdnb.azureedge.net"}; - return [[[MTHttpRequestOperation dataForHttpUrl:[NSURL URLWithString:isTesting ? @"https://software-download.microsoft.com/test/config.txt" : @"https://software-download.microsoft.com/prod/config.txt"] headers:headers] mapToSignal:^MTSignal *(NSData *data) { + return [[[MTHttpRequestOperation dataForHttpUrl:[NSURL URLWithString:isTesting ? @"https://software-download.microsoft.com/testv2/config.txt" : @"https://software-download.microsoft.com/prodv2/config.txt"] headers:headers] mapToSignal:^MTSignal *(NSData *data) { NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; text = [text stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]]; NSData *result = [[NSData alloc] initWithBase64EncodedString:text options:NSDataBase64DecodingIgnoreUnknownCharacters]; NSMutableData *finalData = [[NSMutableData alloc] initWithData:result]; [finalData setLength:256]; - MTBackupDatacenterData *datacenterData = MTIPDataDecode(finalData); + MTBackupDatacenterData *datacenterData = MTIPDataDecode(finalData, phoneNumber); if (datacenterData != nil) { return [MTSignal single:datacenterData]; } else { @@ -86,57 +66,71 @@ }]; } -+ (MTSignal *)fetchBackupIpsResolveGoogle:(bool)isTesting { ++ (MTSignal *)fetchBackupIpsResolveGoogle:(bool)isTesting phoneNumber:(NSString *)phoneNumber { + NSArray *hosts = @[ + @"google.com", + @"www.google.com", + @"google.ru" + ]; NSDictionary *headers = @{@"Host": @"dns.google.com"}; - return [[[MTHttpRequestOperation dataForHttpUrl:[NSURL URLWithString:[NSString stringWithFormat:@"https://google.com/resolve?name=%@&type=16", isTesting ? @"tap.stel.com" : @"ap.stel.com"]] headers:headers] mapToSignal:^MTSignal *(NSData *data) { - NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; - if ([dict respondsToSelector:@selector(objectForKey:)]) { - NSArray *answer = dict[@"Answer"]; - NSMutableArray *strings = [[NSMutableArray alloc] init]; - if ([answer respondsToSelector:@selector(objectAtIndex:)]) { - for (NSDictionary *value in answer) { - if ([value respondsToSelector:@selector(objectForKey:)]) { - NSString *part = value[@"data"]; - if ([part respondsToSelector:@selector(characterAtIndex:)]) { - [strings addObject:part]; + NSMutableArray *signals = [[NSMutableArray alloc] init]; + for (NSString *host in hosts) { + MTSignal *signal = [[[MTHttpRequestOperation dataForHttpUrl:[NSURL URLWithString:[NSString stringWithFormat:@"https://%@/resolve?name=%@&type=16", host, isTesting ? @"tapv2.stel.com" : @"apv2.stel.com"]] headers:headers] mapToSignal:^MTSignal *(NSData *data) { + NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; + if ([dict respondsToSelector:@selector(objectForKey:)]) { + NSArray *answer = dict[@"Answer"]; + NSMutableArray *strings = [[NSMutableArray alloc] init]; + if ([answer respondsToSelector:@selector(objectAtIndex:)]) { + for (NSDictionary *value in answer) { + if ([value respondsToSelector:@selector(objectForKey:)]) { + NSString *part = value[@"data"]; + if ([part respondsToSelector:@selector(characterAtIndex:)]) { + [strings addObject:part]; + } } } - } - [strings sortUsingComparator:^NSComparisonResult(NSString *lhs, NSString *rhs) { - if (lhs.length > rhs.length) { - return NSOrderedAscending; - } else { - return NSOrderedDescending; + [strings sortUsingComparator:^NSComparisonResult(NSString *lhs, NSString *rhs) { + if (lhs.length > rhs.length) { + return NSOrderedAscending; + } else { + return NSOrderedDescending; + } + }]; + + NSString *finalString = @""; + for (NSString *string in strings) { + finalString = [finalString stringByAppendingString:[string stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]]]; + } + + NSData *result = [[NSData alloc] initWithBase64EncodedString:finalString options:NSDataBase64DecodingIgnoreUnknownCharacters]; + NSMutableData *finalData = [[NSMutableData alloc] initWithData:result]; + [finalData setLength:256]; + MTBackupDatacenterData *datacenterData = MTIPDataDecode(finalData, phoneNumber); + if (datacenterData != nil) { + return [MTSignal single:datacenterData]; } - }]; - - NSString *finalString = @""; - for (NSString *string in strings) { - finalString = [finalString stringByAppendingString:[string stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]]]; - } - - NSData *result = [[NSData alloc] initWithBase64EncodedString:finalString options:NSDataBase64DecodingIgnoreUnknownCharacters]; - NSMutableData *finalData = [[NSMutableData alloc] initWithData:result]; - [finalData setLength:256]; - MTBackupDatacenterData *datacenterData = MTIPDataDecode(finalData); - if (datacenterData != nil) { - return [MTSignal single:datacenterData]; } } + return [MTSignal complete]; + }] catch:^MTSignal *(__unused id error) { + return [MTSignal complete]; + }]; + if (signals.count != 0) { + signal = [signal delay:signals.count onQueue:[[MTQueue alloc] init]]; } - return [MTSignal complete]; - }] catch:^MTSignal *(__unused id error) { - return [MTSignal complete]; - }]; + [signals addObject:signal]; + } + + return [[MTSignal mergeSignals:signals] take:1]; } -+ (MTSignal *)fetchConfigFromAddress:(MTBackupDatacenterAddress *)address datacenterId:(NSInteger)datacenterId currentContext:(MTContext *)currentContext { ++ (MTSignal *)fetchConfigFromAddress:(MTBackupDatacenterAddress *)address currentContext:(MTContext *)currentContext { MTApiEnvironment *apiEnvironment = [currentContext.apiEnvironment copy]; NSMutableDictionary *datacenterAddressOverrides = [[NSMutableDictionary alloc] init]; - datacenterAddressOverrides[@(datacenterId)] = [[MTDatacenterAddress alloc] initWithIp:address.ip port:(uint16_t)address.port preferForMedia:false restrictToTcp:false cdn:false preferForProxy:false secret:nil]; + datacenterAddressOverrides[@(address.datacenterId)] = [[MTDatacenterAddress alloc] initWithIp:address.ip port:(uint16_t)address.port preferForMedia:false restrictToTcp:false cdn:false preferForProxy:false secret:address.secret]; apiEnvironment.datacenterAddressOverrides = datacenterAddressOverrides; apiEnvironment.apiId = currentContext.apiEnvironment.apiId; @@ -147,12 +141,12 @@ MTContext *context = [[MTContext alloc] initWithSerialization:currentContext.serialization apiEnvironment:apiEnvironment]; - if (datacenterId != 0) { + if (address.datacenterId != 0) { context.keychain = currentContext.keychain; } - MTProto *mtProto = [[MTProto alloc] initWithContext:context datacenterId:datacenterId usageCalculationInfo:nil]; - if (datacenterId != 0) { + MTProto *mtProto = [[MTProto alloc] initWithContext:context datacenterId:address.datacenterId usageCalculationInfo:nil]; + if (address.datacenterId != 0) { mtProto.useTempAuthKeys = true; } MTRequestMessageService *requestService = [[MTRequestMessageService alloc] initWithContext:context]; @@ -206,15 +200,15 @@ }]; } -+ (MTSignal *)fetchBackupIps:(bool)isTestingEnvironment currentContext:(MTContext *)currentContext { - NSArray *signals = @[[self fetchBackupIpsGoogle:isTestingEnvironment], [self fetchBackupIpsAzure:isTestingEnvironment], [self fetchBackupIpsResolveGoogle:isTestingEnvironment]]; ++ (MTSignal * _Nonnull)fetchBackupIps:(bool)isTestingEnvironment currentContext:(MTContext * _Nonnull)currentContext phoneNumber:(NSString * _Nullable)phoneNumber { + NSArray *signals = @[[self fetchBackupIpsAzure:isTestingEnvironment phoneNumber:phoneNumber], [self fetchBackupIpsResolveGoogle:isTestingEnvironment phoneNumber:phoneNumber]]; return [[[MTSignal mergeSignals:signals] take:1] mapToSignal:^MTSignal *(MTBackupDatacenterData *data) { if (data != nil && data.addressList.count != 0) { NSMutableArray *signals = [[NSMutableArray alloc] init]; NSTimeInterval delay = 0.0; for (MTBackupDatacenterAddress *address in data.addressList) { - MTSignal *signal = [self fetchConfigFromAddress:address datacenterId:data.datacenterId currentContext:currentContext]; + MTSignal *signal = [self fetchConfigFromAddress:address currentContext:currentContext]; if (delay > DBL_EPSILON) { signal = [signal delay:delay onQueue:[[MTQueue alloc] init]]; } diff --git a/MTProtoKit/MTEncryption.h b/MTProtoKit/MTEncryption.h index b7dd3933d0..d209be2e8b 100644 --- a/MTProtoKit/MTEncryption.h +++ b/MTProtoKit/MTEncryption.h @@ -65,21 +65,22 @@ NSData *MTRsaEncryptPKCS1OAEP(NSString *key, NSData *data); @interface MTBackupDatacenterAddress : NSObject +@property (nonatomic, readonly) int32_t datacenterId; @property (nonatomic, strong, readonly) NSString *ip; @property (nonatomic, readonly) int32_t port; +@property (nonatomic, strong, readonly) NSData *secret; @end @interface MTBackupDatacenterData : NSObject -@property (nonatomic, readonly) int32_t datacenterId; @property (nonatomic, readonly) int32_t timestamp; @property (nonatomic, readonly) int32_t expirationDate; @property (nonatomic, strong, readonly) NSArray *addressList; @end -MTBackupDatacenterData *MTIPDataDecode(NSData *data); +MTBackupDatacenterData *MTIPDataDecode(NSData *data, NSString *phoneNumber); #ifdef __cplusplus } diff --git a/MTProtoKit/MTEncryption.m b/MTProtoKit/MTEncryption.m index afc1b31ea0..2152f6e524 100644 --- a/MTProtoKit/MTEncryption.m +++ b/MTProtoKit/MTEncryption.m @@ -806,11 +806,13 @@ static NSData *decrypt_TL_data(unsigned char buffer[256]) { @implementation MTBackupDatacenterAddress -- (instancetype)initWithIp:(NSString *)ip port:(int32_t)port { +- (instancetype)initWithDatacenterId:(int32_t)datacenterId ip:(NSString *)ip port:(int32_t)port secret:(NSData *)secret { self = [super init]; if (self != nil) { + _datacenterId = datacenterId; _ip = ip; _port = port; + _secret = secret; } return self; } @@ -819,10 +821,9 @@ static NSData *decrypt_TL_data(unsigned char buffer[256]) { @implementation MTBackupDatacenterData -- (instancetype)initWithDatacenterId:(int32_t)datacenterId timestamp:(int32_t)timestamp expirationDate:(int32_t)expirationDate addressList:(NSArray *)addressList { +- (instancetype)initWithTimestamp:(int32_t)timestamp expirationDate:(int32_t)expirationDate addressList:(NSArray *)addressList { self = [super init]; if (self != nil) { - _datacenterId = datacenterId; _timestamp = timestamp; _expirationDate = expirationDate; _addressList = addressList; @@ -832,7 +833,7 @@ static NSData *decrypt_TL_data(unsigned char buffer[256]) { @end -MTBackupDatacenterData *MTIPDataDecode(NSData *data) { +MTBackupDatacenterData *MTIPDataDecode(NSData *data, NSString *phoneNumber) { unsigned char buffer[256]; memcpy(buffer, data.bytes, 256); NSData *result = decrypt_TL_data(buffer); @@ -843,48 +844,141 @@ MTBackupDatacenterData *MTIPDataDecode(NSData *data) { if (![reader readInt32:&signature]) { return nil; } - if (signature != 0xd997c3c5) { - return nil; - } - int32_t timestamp = 0; - int32_t expirationDate = 0; - int32_t datacenterId = 0; - if (![reader readInt32:×tamp]) { - return nil; - } - if (![reader readInt32:&expirationDate]) { - return nil; - } - if (![reader readInt32:&datacenterId]) { - return nil; - } - int32_t vectorSignature = 0; - if (![reader readInt32:&vectorSignature]) { - return nil; - } - if (vectorSignature != 0x1cb5c415) { - return nil; - } - - NSMutableArray *addressList = [[NSMutableArray alloc] init]; - int32_t count = 0; - if (![reader readInt32:&count]) { - return nil; - } - - for (int i = 0; i < count; i++) { - int32_t ip = 0; - int32_t port = 0; - if (![reader readInt32:&ip]) { + if (signature == 0xd997c3c5) { + int32_t timestamp = 0; + int32_t expirationDate = 0; + int32_t datacenterId = 0; + if (![reader readInt32:×tamp]) { return nil; } - if (![reader readInt32:&port]) { + if (![reader readInt32:&expirationDate]) { return nil; } - [addressList addObject:[[MTBackupDatacenterAddress alloc] initWithIp:[NSString stringWithFormat:@"%d.%d.%d.%d", (int)((ip >> 24) & 0xFF), (int)((ip >> 16) & 0xFF), (int)((ip >> 8) & 0xFF), (int)((ip >> 0) & 0xFF)] port:port]]; + if (![reader readInt32:&datacenterId]) { + return nil; + } + int32_t vectorSignature = 0; + if (![reader readInt32:&vectorSignature]) { + return nil; + } + if (vectorSignature != 0x1cb5c415) { + return nil; + } + + NSMutableArray *addressList = [[NSMutableArray alloc] init]; + int32_t count = 0; + if (![reader readInt32:&count]) { + return nil; + } + + for (int i = 0; i < count; i++) { + int32_t ip = 0; + int32_t port = 0; + if (![reader readInt32:&ip]) { + return nil; + } + if (![reader readInt32:&port]) { + return nil; + } + [addressList addObject:[[MTBackupDatacenterAddress alloc] initWithDatacenterId:datacenterId ip:[NSString stringWithFormat:@"%d.%d.%d.%d", (int)((ip >> 24) & 0xFF), (int)((ip >> 16) & 0xFF), (int)((ip >> 8) & 0xFF), (int)((ip >> 0) & 0xFF)] port:port secret:nil]]; + } + + return [[MTBackupDatacenterData alloc] initWithTimestamp:timestamp expirationDate:expirationDate addressList:addressList]; + } else if (signature == 0x5a592a6c) { + int32_t timestamp = 0; + int32_t expirationDate = 0; + if (![reader readInt32:×tamp]) { + return nil; + } + if (![reader readInt32:&expirationDate]) { + return nil; + } + + NSMutableArray *addressList = [[NSMutableArray alloc] init]; + int32_t count = 0; + if (![reader readInt32:&count]) { + return nil; + } + + for (int32_t i = 0; i < count; i++) { + int32_t signature = 0; + if (![reader readInt32:&signature]) { + return nil; + } + if (signature != 0x4679b65f) { + return nil; + } + NSString *phonePrefixRules = nil; + if (![reader readTLString:&phonePrefixRules]) { + return nil; + } + int32_t datacenterId = 0; + if (![reader readInt32:&datacenterId]) { + return nil; + } + + int32_t ipCount = 0; + if (![reader readInt32:&ipCount]) { + return nil; + } + + NSMutableArray *ruleAddressList = [[NSMutableArray alloc] init]; + + for (int j = 0; j < ipCount; j++) { + int32_t signature = 0; + if (![reader readInt32:&signature]) { + return nil; + } + if (signature == 0xd433ad73) { + int32_t ip = 0; + int32_t port = 0; + if (![reader readInt32:&ip]) { + return nil; + } + if (![reader readInt32:&port]) { + return nil; + } + [ruleAddressList addObject:[[MTBackupDatacenterAddress alloc] initWithDatacenterId:datacenterId ip:[NSString stringWithFormat:@"%d.%d.%d.%d", (int)((ip >> 24) & 0xFF), (int)((ip >> 16) & 0xFF), (int)((ip >> 8) & 0xFF), (int)((ip >> 0) & 0xFF)] port:port secret:nil]]; + } else if (signature == 0x37982646) { + int32_t ip = 0; + int32_t port = 0; + if (![reader readInt32:&ip]) { + return nil; + } + if (![reader readInt32:&port]) { + return nil; + } + NSData *secret = nil; + if (![reader readTLBytes:&secret]) { + return nil; + } + [ruleAddressList addObject:[[MTBackupDatacenterAddress alloc] initWithDatacenterId:datacenterId ip:[NSString stringWithFormat:@"%d.%d.%d.%d", (int)((ip >> 24) & 0xFF), (int)((ip >> 16) & 0xFF), (int)((ip >> 8) & 0xFF), (int)((ip >> 0) & 0xFF)] port:port secret:secret]]; + } else { + return nil; + } + } + + bool includeIp = true; + for (NSString *rule in [phonePrefixRules componentsSeparatedByString:@","]) { + if (rule.length == 0) { + includeIp = true; + } else if ([rule characterAtIndex:0] == '+' && [phoneNumber hasPrefix:[rule substringFromIndex:1]]) { + includeIp = true; + } else if ([rule characterAtIndex:0] == '-' && [phoneNumber hasPrefix:[rule substringFromIndex:1]]) { + includeIp = false; + } else { + includeIp = false; + } + } + if (includeIp) { + [addressList addObjectsFromArray:ruleAddressList]; + } + } + + return [[MTBackupDatacenterData alloc] initWithTimestamp:timestamp expirationDate:expirationDate addressList:addressList]; + } else { + return nil; } - - return [[MTBackupDatacenterData alloc] initWithDatacenterId:datacenterId timestamp:timestamp expirationDate:expirationDate addressList:addressList]; } else { return nil; } diff --git a/MTProtoKit/MTTcpConnection.m b/MTProtoKit/MTTcpConnection.m index df14c8e39c..2dc56bfa94 100644 --- a/MTProtoKit/MTTcpConnection.m +++ b/MTProtoKit/MTTcpConnection.m @@ -281,11 +281,11 @@ struct ctr_state { isHostname = false; } - if (isHostname) { + /*if (isHostname) { resolveSignal = [MTDNS resolveHostname:_socksIp]; - } else { + } else {*/ resolveSignal = [MTSignal single:_socksIp]; - } + //} } else if (_mtpIp != nil) { port = _mtpPort; @@ -298,11 +298,11 @@ struct ctr_state { isHostname = false; } - if (isHostname) { + /*if (isHostname) { resolveSignal = [MTDNS resolveHostname:_mtpIp]; - } else { + } else {*/ resolveSignal = [MTSignal single:_mtpIp]; - } + //} } __weak MTTcpConnection *weakSelf = self;