no message

This commit is contained in:
Peter
2018-05-01 16:42:05 +03:00
parent c2aee5f7e2
commit be2ee63fd3
5 changed files with 205 additions and 116 deletions

View File

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

View File

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

View File

@@ -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<MTBackupDatacenterAddress *> *addressList;
@end
MTBackupDatacenterData *MTIPDataDecode(NSData *data);
MTBackupDatacenterData *MTIPDataDecode(NSData *data, NSString *phoneNumber);
#ifdef __cplusplus
}

View File

@@ -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<MTBackupDatacenterAddress *> *)addressList {
- (instancetype)initWithTimestamp:(int32_t)timestamp expirationDate:(int32_t)expirationDate addressList:(NSArray<MTBackupDatacenterAddress *> *)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:&timestamp]) {
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<MTBackupDatacenterAddress *> *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:&timestamp]) {
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<MTBackupDatacenterAddress *> *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:&timestamp]) {
return nil;
}
if (![reader readInt32:&expirationDate]) {
return nil;
}
NSMutableArray<MTBackupDatacenterAddress *> *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<MTBackupDatacenterAddress *> *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;
}

View File

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