This commit is contained in:
Mikhail Filimonov
2018-05-03 12:54:23 +04:00
13 changed files with 406 additions and 166 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 additionalSource:(MTSignal * _Nullable)additionalSource 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;
@@ -145,15 +139,15 @@
apiEnvironment.disableUpdates = true;
apiEnvironment.langPack = currentContext.apiEnvironment.langPack;
MTContext *context = [[MTContext alloc] initWithSerialization:currentContext.serialization apiEnvironment:apiEnvironment];
MTContext *context = [[MTContext alloc] initWithSerialization:currentContext.serialization apiEnvironment:apiEnvironment useTempAuthKeys:address.datacenterId != 0 ? currentContext.useTempAuthKeys : false];
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.useTempAuthKeys = true;
MTProto *mtProto = [[MTProto alloc] initWithContext:context datacenterId:address.datacenterId usageCalculationInfo:nil];
if (address.datacenterId != 0) {
mtProto.useTempAuthKeys = currentContext.useTempAuthKeys;
}
MTRequestMessageService *requestService = [[MTRequestMessageService alloc] initWithContext:context];
[mtProto addMessageService:requestService];
@@ -206,15 +200,20 @@
}];
}
+ (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 additionalSource:(MTSignal * _Nullable)additionalSource phoneNumber:(NSString * _Nullable)phoneNumber {
NSMutableArray *signals = [[NSMutableArray alloc] init];
[signals addObject:[self fetchBackupIpsAzure:isTestingEnvironment phoneNumber:phoneNumber]];
[signals addObject:[self fetchBackupIpsResolveGoogle:isTestingEnvironment phoneNumber:phoneNumber]];
if (additionalSource != nil) {
[signals addObject:additionalSource];
}
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

@@ -20,6 +20,14 @@
@end
@interface MTNetworkSettings : NSObject
@property (nonatomic, readonly) bool reducedBackupDiscoveryTimeout;
- (instancetype)initWithReducedBackupDiscoveryTimeout:(bool)reducedBackupDiscoveryTimeout;
@end
@interface MTApiEnvironment : NSObject
@property (nonatomic) int32_t apiId;
@@ -39,10 +47,12 @@
@property (nonatomic) NSDictionary *datacenterAddressOverrides;
@property (nonatomic, strong, readonly) MTSocksProxySettings *socksProxySettings;
@property (nonatomic, strong, readonly) MTNetworkSettings *networkSettings;
@property (nonatomic, copy) void (^passwordInputHandler)();
- (MTApiEnvironment *)withUpdatedLangPackCode:(NSString *)langPackCode;
- (MTApiEnvironment *)withUpdatedSocksProxySettings:(MTSocksProxySettings *)socksProxySettings;
- (MTApiEnvironment *)withUpdatedNetworkSettings:(MTNetworkSettings *)networkSettings;
@end

View File

@@ -169,6 +169,29 @@ typedef enum {
@end
@implementation MTNetworkSettings
- (instancetype)initWithReducedBackupDiscoveryTimeout:(bool)reducedBackupDiscoveryTimeout {
self = [super init];
if (self != nil) {
_reducedBackupDiscoveryTimeout = reducedBackupDiscoveryTimeout;
}
return self;
}
- (BOOL)isEqual:(id)object {
if (![object isKindOfClass:[MTNetworkSettings class]]) {
return false;
}
MTNetworkSettings *other = object;
if (_reducedBackupDiscoveryTimeout != other->_reducedBackupDiscoveryTimeout) {
return false;
}
return true;
}
@end
@implementation MTApiEnvironment
- (instancetype)init
@@ -415,6 +438,7 @@ NSString *suffix = @"";
result.tcpPayloadPrefix = self.tcpPayloadPrefix;
result.datacenterAddressOverrides = self.datacenterAddressOverrides;
result->_socksProxySettings = self.socksProxySettings;
result->_networkSettings = self.networkSettings;
[result _updateApiInitializationHash];
@@ -432,6 +456,7 @@ NSString *suffix = @"";
result->_langPackCode = self.langPackCode;
result->_socksProxySettings = self.socksProxySettings;
result->_networkSettings = self.networkSettings;
result.disableUpdates = self.disableUpdates;
result.tcpPayloadPrefix = self.tcpPayloadPrefix;
@@ -453,6 +478,29 @@ NSString *suffix = @"";
result->_langPackCode = self.langPackCode;
result->_socksProxySettings = socksProxySettings;
result->_networkSettings = self.networkSettings;
result.disableUpdates = self.disableUpdates;
result.tcpPayloadPrefix = self.tcpPayloadPrefix;
result.datacenterAddressOverrides = self.datacenterAddressOverrides;
[result _updateApiInitializationHash];
return result;
}
- (MTApiEnvironment *)withUpdatedNetworkSettings:(MTNetworkSettings *)networkSettings {
MTApiEnvironment *result = [[MTApiEnvironment alloc] init];
result.apiId = self.apiId;
result.appVersion = self.appVersion;
result.layer = self.layer;
result.langPack = self.langPack;
result->_langPackCode = self.langPackCode;
result->_socksProxySettings = self.socksProxySettings;
result->_networkSettings = networkSettings;
result.disableUpdates = self.disableUpdates;
result.tcpPayloadPrefix = self.tcpPayloadPrefix;

View File

@@ -48,8 +48,9 @@
@property (nonatomic, strong, readonly) id<MTSerialization> serialization;
@property (nonatomic, strong, readonly) MTApiEnvironment *apiEnvironment;
@property (nonatomic, readonly) bool useTempAuthKeys;
- (instancetype)initWithSerialization:(id<MTSerialization>)serialization apiEnvironment:(MTApiEnvironment *)apiEnvironment;
- (instancetype)initWithSerialization:(id<MTSerialization>)serialization apiEnvironment:(MTApiEnvironment *)apiEnvironment useTempAuthKeys:(bool)useTempAuthKeys;
- (void)performBatchUpdates:(void (^)())block;

View File

@@ -125,7 +125,7 @@
return self;
}
- (instancetype)initWithSerialization:(id<MTSerialization>)serialization apiEnvironment:(MTApiEnvironment *)apiEnvironment
- (instancetype)initWithSerialization:(id<MTSerialization>)serialization apiEnvironment:(MTApiEnvironment *)apiEnvironment useTempAuthKeys:(bool)useTempAuthKeys
{
#ifdef DEBUG
NSAssert(serialization != nil, @"serialization should not be nil");
@@ -139,6 +139,7 @@
_serialization = serialization;
_apiEnvironment = apiEnvironment;
_useTempAuthKeys = useTempAuthKeys;
_datacenterSeedAddressSetById = [[NSMutableDictionary alloc] init];
@@ -1009,6 +1010,9 @@
if (_backupAddressListDisposable == nil && _discoverBackupAddressListSignal != nil) {
__weak MTContext *weakSelf = self;
double delay = 20.0f;
if (_apiEnvironment.networkSettings.reducedBackupDiscoveryTimeout) {
delay = 5.0;
}
#ifdef DEBUG
delay = 5.0;
#endif

View File

@@ -91,7 +91,7 @@
}
_sourceDatacenterMtProto = [[MTProto alloc] initWithContext:context datacenterId:sourceDatacenterId usageCalculationInfo:nil];
_sourceDatacenterMtProto.useTempAuthKeys = true;
_sourceDatacenterMtProto.useTempAuthKeys = context.useTempAuthKeys;
MTRequestMessageService *requestService = [[MTRequestMessageService alloc] initWithContext:context];
[_sourceDatacenterMtProto addMessageService:requestService];
@@ -128,7 +128,7 @@
MTContext *context = _context;
_destinationDatacenterMtProto = [[MTProto alloc] initWithContext:context datacenterId:_destinationDatacenterId usageCalculationInfo:nil];
_destinationDatacenterMtProto.useTempAuthKeys = true;
_destinationDatacenterMtProto.useTempAuthKeys = context.useTempAuthKeys;
MTRequestMessageService *requestService = [[MTRequestMessageService alloc] initWithContext:context];
[_destinationDatacenterMtProto addMessageService:requestService];

View File

@@ -78,7 +78,7 @@
if (datacenterAddressIsKnown)
[self complete];
else if (currentDatacenterId != 0)
[self askForAnAddressDatacenterWithId:currentDatacenterId];
[self askForAnAddressDatacenterWithId:currentDatacenterId useTempAuthKeys:context.useTempAuthKeys];
else
[self fail];
}
@@ -86,7 +86,7 @@
[self fail];
}
- (void)askForAnAddressDatacenterWithId:(NSInteger)targetDatacenterId
- (void)askForAnAddressDatacenterWithId:(NSInteger)targetDatacenterId useTempAuthKeys:(bool)useTempAuthKeys
{
_targetDatacenterId = targetDatacenterId;
@@ -99,7 +99,7 @@
if ([context authInfoForDatacenterWithId:_targetDatacenterId] != nil)
{
_mtProto = [[MTProto alloc] initWithContext:context datacenterId:_targetDatacenterId usageCalculationInfo:nil];
_mtProto.useTempAuthKeys = true;
_mtProto.useTempAuthKeys = useTempAuthKeys;
_requestService = [[MTRequestMessageService alloc] initWithContext:_context];
[_mtProto addMessageService:_requestService];
@@ -138,7 +138,7 @@
{
_awaitingAddresSetUpdate = false;
[self askForAnAddressDatacenterWithId:datacenterId];
[self askForAnAddressDatacenterWithId:datacenterId useTempAuthKeys:context.useTempAuthKeys];
}
}

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

@@ -26,10 +26,38 @@
#import "MTAes.h"
#import "MTEncryption.h"
#import "MTDNS.h"
#import "MTSignal.h"
#if defined(MtProtoKitDynamicFramework)
# import <MTProtoKitDynamic/MTSignal.h>
# import <MTProtoKitDynamic/MTDNS.h>
#elif defined(MtProtoKitMacFramework)
# import <MTProtoKitMac/MTSignal.h>
# import <MTProtoKitMac/MTDNS.h>
#else
# import <MTProtoKit/MTSignal.h>
# import <MTProtoKit/MTDNS.h>
#endif
#define MT_TCPO25 1
@interface MTTcpConnectionData : NSObject
@property (nonatomic, strong, readonly) NSString *ip;
@property (nonatomic, readonly) int32_t port;
@property (nonatomic, readonly) bool isSocks;
@end
@implementation MTTcpConnectionData
- (instancetype)initWithIp:(NSString *)ip port:(int32_t)port isSocks:(bool)isSocks {
self = [super init];
if (self != nil) {
_ip = ip;
_port = port;
_isSocks = isSocks;
}
return self;
}
@end
MTInternalIdClass(MTTcpConnection)
@@ -252,26 +280,9 @@ struct ctr_state {
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:[[MTTcpConnection tcpQueue] nativeQueue]];
_socket.usageCalculationInfo = _usageCalculationInfo;
if (MTLogEnabled()) {
if (_socksIp != nil) {
if (_socksUsername.length == 0) {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d via %@:%d]", (int)self, _address.ip, (int)_address.port, _socksIp, (int)_socksPort);
} else {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d via %@:%d using %@:%@]", (int)self, _address.ip, (int)_address.port, _socksIp, (int)_socksPort, _socksUsername, _socksPassword);
}
} else if (_mtpIp != nil) {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d via mtp://%@:%d:%@]", (int)self, _address.ip, (int)_address.port, _mtpIp, (int)_mtpPort, _mtpSecret);
} else {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d]", (int)self, _address.ip, (int)_address.port);
}
}
MTSignal *resolveSignal = [MTSignal single:_address.ip];
uint16_t port = _address.port;
MTSignal *resolveSignal = [MTSignal single:[[MTTcpConnectionData alloc] initWithIp:_address.ip port:_address.port isSocks:false]];
if (_socksIp != nil) {
port = _socksPort;
bool isHostname = true;
struct in_addr ip4;
struct in6_addr ip6;
@@ -281,14 +292,12 @@ struct ctr_state {
isHostname = false;
}
if (isHostname) {
/*if (isHostname) {
resolveSignal = [MTDNS resolveHostname:_socksIp];
} else {
resolveSignal = [MTSignal single:_socksIp];
}
} else {*/
resolveSignal = [MTSignal single:[[MTTcpConnectionData alloc] initWithIp:_socksIp port:_socksPort isSocks:true]];
//}
} else if (_mtpIp != nil) {
port = _mtpPort;
bool isHostname = true;
struct in_addr ip4;
struct in6_addr ip6;
@@ -298,26 +307,45 @@ struct ctr_state {
isHostname = false;
}
if (isHostname) {
/*if (isHostname) {
resolveSignal = [MTDNS resolveHostname:_mtpIp];
} else {
resolveSignal = [MTSignal single:_mtpIp];
}
} else {*/
resolveSignal = [MTSignal single:[[MTTcpConnectionData alloc] initWithIp:_mtpIp port:_mtpPort isSocks:false]];
//}
}
__weak MTTcpConnection *weakSelf = self;
[_resolveDisposable setDisposable:[resolveSignal startWithNext:^(NSString *ip) {
[_resolveDisposable setDisposable:[resolveSignal startWithNext:^(MTTcpConnectionData *connectionData) {
[[MTTcpConnection tcpQueue] dispatchOnQueue:^{
__strong MTTcpConnection *strongSelf = weakSelf;
if (strongSelf == nil || ip == nil) {
if (strongSelf == nil || connectionData == nil) {
return;
}
if (![ip respondsToSelector:@selector(characterAtIndex:)]) {
if (![connectionData.ip respondsToSelector:@selector(characterAtIndex:)]) {
return;
}
if (connectionData.isSocks) {
strongSelf->_socksIp = connectionData.ip;
strongSelf->_socksPort = connectionData.port;
}
if (MTLogEnabled()) {
if (strongSelf->_socksIp != nil) {
if (strongSelf->_socksUsername.length == 0) {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d via %@:%d]", (int)self, strongSelf->_address.ip, (int)strongSelf->_address.port, strongSelf->_socksIp, (int)strongSelf->_socksPort);
} else {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d via %@:%d using %@:%@]", (int)self, strongSelf->_address.ip, (int)strongSelf->_address.port, strongSelf->_socksIp, (int)_socksPort, strongSelf->_socksUsername, strongSelf->_socksPassword);
}
} else if (strongSelf->_mtpIp != nil) {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d via mtp://%@:%d:%@]", (int)self, strongSelf->_address.ip, (int)strongSelf->_address.port, strongSelf->_mtpIp, (int)strongSelf->_mtpPort, strongSelf->_mtpSecret);
} else {
MTLog(@"[MTTcpConnection#%x connecting to %@:%d]", (int)self, strongSelf->_address.ip, (int)strongSelf->_address.port);
}
}
__autoreleasing NSError *error = nil;
if (![strongSelf->_socket connectToHost:ip onPort:port viaInterface:strongSelf->_interface withTimeout:12 error:&error] || error != nil) {
if (![strongSelf->_socket connectToHost:connectionData.ip onPort:connectionData.port viaInterface:strongSelf->_interface withTimeout:12 error:&error] || error != nil) {
[strongSelf closeAndNotify];
} else if (strongSelf->_socksIp == nil) {
[strongSelf->_socket readDataToLength:1 withTimeout:-1 tag:MTTcpReadTagPacketShortLength];
@@ -441,7 +469,7 @@ struct ctr_state {
NSData *incomingAesKey = [[NSData alloc] initWithBytes:controlBytesReversed + 8 length:32];
NSData *incomingAesIv = [[NSData alloc] initWithBytes:controlBytesReversed + 8 + 32 length:16];
#if MT_TCPO25
if (_mtpSecret != nil || _address.secret != nil) {
NSMutableData *aesKeyData = [[NSMutableData alloc] init];
[aesKeyData appendData:aesKey];
@@ -463,7 +491,6 @@ struct ctr_state {
NSData *incomingAesKeyHash = MTSha256(incomingAesKeyData);
incomingAesKey = [incomingAesKeyHash subdataWithRange:NSMakeRange(0, 32)];
}
#endif
_outgoingAesCtr = [[MTAesCtr alloc] initWithKey:aesKey.bytes keyLength:32 iv:aesIv.bytes decrypt:false];
_incomingAesCtr = [[MTAesCtr alloc] initWithKey:incomingAesKey.bytes keyLength:32 iv:incomingAesIv.bytes decrypt:false];

View File

@@ -1,13 +1,33 @@
#import "MTProxyConnectivity.h"
#import "MTSignal.h"
#import "MTQueue.h"
#import "MTContext.h"
#import "MTApiEnvironment.h"
#import "MTDatacenterAddressSet.h"
#import "MTDatacenterAddress.h"
#import "MTTcpConnection.h"
#import "MTTransportScheme.h"
#if defined(MtProtoKitDynamicFramework)
# import <MTProtoKitDynamic/MTSignal.h>
# import <MTProtoKitDynamic/MTQueue.h>
# import <MTProtoKitDynamic/MTContext.h>
# import <MTProtoKitDynamic/MTApiEnvironment.h>
# import <MTProtoKitDynamic/MTDatacenterAddressSet.h>
# import <MTProtoKitDynamic/MTDatacenterAddress.h>
# import <MTProtoKitDynamic/MTTcpConnection.h>
# import <MTProtoKitDynamic/MTTransportScheme.h>
#elif defined(MtProtoKitMacFramework)
# import <MTProtoKitMac/MTSignal.h>
# import <MTProtoKitMac/MTQueue.h>
# import <MTProtoKitMac/MTContext.h>
# import <MTProtoKitMac/MTApiEnvironment.h>
# import <MTProtoKitMac/MTDatacenterAddressSet.h>
# import <MTProtoKitMac/MTDatacenterAddress.h>
# import <MTProtoKitMac/MTTcpConnection.h>
# import <MTProtoKitMac/MTTransportScheme.h>
#else
# import <MTProtoKit/MTSignal.h>
# import <MTProtoKit/MTQueue.h>
# import <MTProtoKit/MTContext.h>
# import <MTProtoKit/MTApiEnvironment.h>
# import <MTProtoKit/MTDatacenterAddressSet.h>
# import <MTProtoKit/MTDatacenterAddress.h>
# import <MTProtoKit/MTTcpConnection.h>
# import <MTProtoKit/MTTransportScheme.h>
#endif
@implementation MTProxyConnectivityStatus
@@ -88,7 +108,7 @@ typedef struct {
MTPayloadData payloadData;
NSData *data = [self payloadData:&payloadData];
MTContext *proxyContext = [[MTContext alloc] initWithSerialization:context.serialization apiEnvironment:[[context apiEnvironment] withUpdatedSocksProxySettings:settings]];
MTContext *proxyContext = [[MTContext alloc] initWithSerialization:context.serialization apiEnvironment:[[context apiEnvironment] withUpdatedSocksProxySettings:settings] useTempAuthKeys:context.useTempAuthKeys];
MTTcpConnection *connection = [[MTTcpConnection alloc] initWithContext:proxyContext datacenterId:datacenterId address:address interface:nil usageCalculationInfo:nil];
__weak MTTcpConnection *weakConnection = connection;

View File

@@ -2467,6 +2467,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl";
@@ -2897,6 +2901,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -3121,6 +3129,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl";
INFOPLIST_FILE = MtProtoKitDynamic/Info.plist;
@@ -3334,6 +3346,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl";
INFOPLIST_FILE = MtProtoKitDynamic/Info.plist;
@@ -3546,6 +3562,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl";
INFOPLIST_FILE = MtProtoKitDynamic/Info.plist;
@@ -3758,6 +3778,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl";
INFOPLIST_FILE = MtProtoKitDynamic/Info.plist;
@@ -3951,6 +3975,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -4001,6 +4029,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/openssl";
INFOPLIST_FILE = MtProtoKitDynamic/Info.plist;
@@ -4239,6 +4271,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/thirdparty",
);
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",