From d569f8279744644d8d44ea966512334cc5dd020c Mon Sep 17 00:00:00 2001 From: Peter <> Date: Fri, 15 Mar 2019 21:13:25 +0400 Subject: [PATCH] Update submodules --- .../NotificationViewController.swift | 2 +- Share/ShareRootController.swift | 2 +- SiriIntents/IntentHandler.swift | 2 +- Telegram-iOS/AppDelegate.swift | 211 +++++++++----- Telegram-iOS/ApplicationContext.swift | 8 +- Telegram-iOS/BuildConfig.h | 1 + Telegram-iOS/BuildConfig.m | 271 ++++++++++++++++++ Telegram-iOS/LegacyPreferencesImport.swift | 15 +- Telegram-iOS/en.lproj/Localizable.strings | 2 + Widget/TodayViewController.swift | 2 +- submodules/MtProtoKit | 2 +- submodules/TelegramCore | 2 +- submodules/TelegramUI | 2 +- submodules/libtgvoip | 2 +- 14 files changed, 430 insertions(+), 94 deletions(-) diff --git a/NotificationContent/NotificationViewController.swift b/NotificationContent/NotificationViewController.swift index 8bd411f3c9..346460738c 100644 --- a/NotificationContent/NotificationViewController.swift +++ b/NotificationContent/NotificationViewController.swift @@ -117,7 +117,7 @@ class NotificationViewController: UIViewController, UNNotificationContentExtensi let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown" - sharedAccountContext = SharedAccountContext(mainWindow: nil, basePath: rootPath, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) + sharedAccountContext = SharedAccountContext(mainWindow: nil, basePath: rootPath, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: BuildConfig.shared().bundleData), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) } } diff --git a/Share/ShareRootController.swift b/Share/ShareRootController.swift index d3d5ecd8c2..eb5e5fbcb5 100644 --- a/Share/ShareRootController.swift +++ b/Share/ShareRootController.swift @@ -160,7 +160,7 @@ class ShareRootController: UIViewController { }) semaphore.wait() - let sharedContext = SharedAccountContext(mainWindow: nil, basePath: rootPath, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) + let sharedContext = SharedAccountContext(mainWindow: nil, basePath: rootPath, accountManager: accountManager, applicationBindings: applicationBindings, initialPresentationDataAndSettings: initialPresentationDataAndSettings!, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: BuildConfig.shared().bundleData), rootPath: rootPath, legacyBasePath: nil, legacyCache: nil, apsNotificationToken: .never(), voipNotificationToken: .never(), setNotificationCall: { _ in }, navigateToChat: { _, _, _ in }) sharedExtensionContext = SharedExtensionContext(sharedContext: sharedContext) globalSharedExtensionContext = sharedExtensionContext } diff --git a/SiriIntents/IntentHandler.swift b/SiriIntents/IntentHandler.swift index 59cb28dfbf..5710b215ae 100644 --- a/SiriIntents/IntentHandler.swift +++ b/SiriIntents/IntentHandler.swift @@ -84,7 +84,7 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag initializeAccountManagement() let accountManager = AccountManager(basePath: rootPath + "/accounts-metadata") - account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods) + account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: BuildConfig.shared().bundleData), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: accountAuxiliaryMethods) |> mapToSignal { account -> Signal in if let account = account { switch account { diff --git a/Telegram-iOS/AppDelegate.swift b/Telegram-iOS/AppDelegate.swift index 0eb93f2277..185cfa3403 100644 --- a/Telegram-iOS/AppDelegate.swift +++ b/Telegram-iOS/AppDelegate.swift @@ -344,7 +344,7 @@ private final class SharedApplicationContext { let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown" - let networkArguments = NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: PresentationCallManager.voipMaxLayer) + let networkArguments = NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: PresentationCallManager.voipMaxLayer, appData: BuildConfig.shared().bundleData) let appGroupName = "group.\(Bundle.main.bundleIdentifier!)" let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName) @@ -1612,81 +1612,84 @@ private final class SharedApplicationContext { @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { - if response.actionIdentifier == UNNotificationDefaultActionIdentifier { - if let peerId = peerIdFromNotification(response.notification) { - var messageId: MessageId? = nil - if response.notification.request.content.categoryIdentifier == "watch" { - messageId = messageIdFromNotification(peerId: peerId, notification: response.notification) - } - self.openChatWhenReady(accountId: accountIdFromNotification(response.notification), peerId: peerId, messageId: messageId) - } - completionHandler() - } else if response.actionIdentifier == "reply", let peerId = peerIdFromNotification(response.notification), let accountId = accountIdFromNotification(response.notification) { - guard let response = response as? UNTextInputNotificationResponse, !response.userText.isEmpty else { - completionHandler() - return - } - let text = response.userText - let signal = self.sharedContextPromise.get() - |> take(1) - |> deliverOnMainQueue - |> mapToSignal { sharedContext -> Signal in - sharedContext.wakeupManager.allowBackgroundTimeExtension(timeout: 4.0) - return sharedContext.sharedContext.activeAccounts - |> mapToSignal { _, accounts, _ -> Signal in - for account in accounts { - if account.1.id == accountId { - return .single(account.1) - } + let _ = (accountIdFromNotification(response.notification, sharedContext: self.sharedContextPromise.get()) + |> deliverOnMainQueue).start(next: { accountId in + if response.actionIdentifier == UNNotificationDefaultActionIdentifier { + if let peerId = peerIdFromNotification(response.notification) { + var messageId: MessageId? = nil + if response.notification.request.content.categoryIdentifier == "watch" { + messageId = messageIdFromNotification(peerId: peerId, notification: response.notification) } - return .complete() + self.openChatWhenReady(accountId: accountId, peerId: peerId, messageId: messageId) } + completionHandler() + } else if response.actionIdentifier == "reply", let peerId = peerIdFromNotification(response.notification), let accountId = accountId { + guard let response = response as? UNTextInputNotificationResponse, !response.userText.isEmpty else { + completionHandler() + return + } + let text = response.userText + let signal = self.sharedContextPromise.get() |> take(1) |> deliverOnMainQueue - |> mapToSignal { account -> Signal in - if let messageId = messageIdFromNotification(peerId: peerId, notification: response.notification) { - let _ = applyMaxReadIndexInteractively(postbox: account.postbox, stateManager: account.stateManager, index: MessageIndex(id: messageId, timestamp: 0)).start() - } - return enqueueMessages(account: account, peerId: peerId, messages: [EnqueueMessage.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)]) - |> map { messageIds -> MessageId? in - if messageIds.isEmpty { - return nil - } else { - return messageIds[0] - } - } - |> mapToSignal { messageId -> Signal in - if let messageId = messageId { - return account.postbox.unsentMessageIdsView() - |> filter { view in - return !view.ids.contains(messageId) + |> mapToSignal { sharedContext -> Signal in + sharedContext.wakeupManager.allowBackgroundTimeExtension(timeout: 4.0) + return sharedContext.sharedContext.activeAccounts + |> mapToSignal { _, accounts, _ -> Signal in + for account in accounts { + if account.1.id == accountId { + return .single(account.1) } - |> take(1) - |> mapToSignal { _ -> Signal in + } + return .complete() + } + |> take(1) + |> deliverOnMainQueue + |> mapToSignal { account -> Signal in + if let messageId = messageIdFromNotification(peerId: peerId, notification: response.notification) { + let _ = applyMaxReadIndexInteractively(postbox: account.postbox, stateManager: account.stateManager, index: MessageIndex(id: messageId, timestamp: 0)).start() + } + return enqueueMessages(account: account, peerId: peerId, messages: [EnqueueMessage.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)]) + |> map { messageIds -> MessageId? in + if messageIds.isEmpty { + return nil + } else { + return messageIds[0] + } + } + |> mapToSignal { messageId -> Signal in + if let messageId = messageId { + return account.postbox.unsentMessageIdsView() + |> filter { view in + return !view.ids.contains(messageId) + } + |> take(1) + |> mapToSignal { _ -> Signal in + return .complete() + } + } else { return .complete() } - } else { - return .complete() } } } - } - |> deliverOnMainQueue - - let disposable = MetaDisposable() - disposable.set((signal - |> afterDisposed { [weak disposable] in - Queue.mainQueue().async { - if let disposable = disposable { - self.replyFromNotificationsDisposables.remove(disposable) + |> deliverOnMainQueue + + let disposable = MetaDisposable() + disposable.set((signal + |> afterDisposed { [weak disposable] in + Queue.mainQueue().async { + if let disposable = disposable { + self.replyFromNotificationsDisposables.remove(disposable) + } + completionHandler() } - completionHandler() - } - }).start()) - self.replyFromNotificationsDisposables.add(disposable) - } else { - completionHandler() - } + }).start()) + self.replyFromNotificationsDisposables.add(disposable) + } else { + completionHandler() + } + }) } private func registerForNotifications(context: AccountContext, authorize: Bool = true, completion: @escaping (Bool) -> Void = { _ in }) { @@ -1884,11 +1887,14 @@ private final class SharedApplicationContext { @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { - if let context = self.contextValue { - if let accountId = accountIdFromNotification(notification), context.context.account.id != accountId { - completionHandler([.alert]) + let _ = (accountIdFromNotification(notification, sharedContext: self.sharedContextPromise.get()) + |> deliverOnMainQueue).start(next: { accountId in + if let context = self.contextValue { + if let accountId = accountId, context.context.account.id != accountId { + completionHandler([.alert]) + } } - } + }) } override var next: UIResponder? { @@ -1913,13 +1919,70 @@ private final class SharedApplicationContext { } } -@available(iOS 10.0, *) -private func accountIdFromNotification(_ notification: UNNotification) -> AccountRecordId? { - if let id = notification.request.content.userInfo["accountId"] as? Int64 { - return AccountRecordId(rawValue: id) - } else { +private func notificationPayloadKey(data: Data) -> Data? { + if data.count < 8 { return nil } + return data.subdata(in: 0 ..< 8) +} + +@available(iOS 10.0, *) +private func accountIdFromNotification(_ notification: UNNotification, sharedContext: Signal) -> Signal { + if let id = notification.request.content.userInfo["accountId"] as? Int64 { + return .single(AccountRecordId(rawValue: id)) + } else { + var encryptedData: Data? + if var encryptedPayload = notification.request.content.userInfo["p"] as? String { + encryptedPayload = encryptedPayload.replacingOccurrences(of: "-", with: "+") + encryptedPayload = encryptedPayload.replacingOccurrences(of: "_", with: "/") + while encryptedPayload.count % 4 != 0 { + encryptedPayload.append("=") + } + encryptedData = Data(base64Encoded: encryptedPayload) + } + if let encryptedData = encryptedData, let notificationKeyId = notificationPayloadKey(data: encryptedData) { + return sharedContext + |> take(1) + |> mapToSignal { sharedContext -> Signal in + return sharedContext.sharedContext.activeAccounts + |> take(1) + |> mapToSignal { _, accounts, _ -> Signal in + let keys = accounts.map { _, account, _ -> Signal<(AccountRecordId, MasterNotificationKey)?, NoError> in + return masterNotificationsKey(account: account, ignoreDisabled: true) + |> map { key in + return (account.id, key) + } + } + return combineLatest(keys) + |> map { keys -> AccountRecordId? in + for idAndKey in keys { + if let (id, key) = idAndKey, key.id == notificationKeyId { + return id + } + } + return nil + } + } + } + } else if let userId = notification.request.content.userInfo["userId"] as? Int { + return sharedContext + |> take(1) + |> mapToSignal { sharedContext -> Signal in + return sharedContext.sharedContext.activeAccounts + |> take(1) + |> map { _, accounts, _ -> AccountRecordId? in + for (_, account, _) in accounts { + if Int(account.peerId.id) == userId { + return account.id + } + } + return nil + } + } + } else { + return .single(nil) + } + } } @available(iOS 10.0, *) diff --git a/Telegram-iOS/ApplicationContext.swift b/Telegram-iOS/ApplicationContext.swift index b2940f9d10..cc59a2f164 100644 --- a/Telegram-iOS/ApplicationContext.swift +++ b/Telegram-iOS/ApplicationContext.swift @@ -712,10 +712,10 @@ final class AuthorizedApplicationContext { }) let importableContacts = self.context.sharedContext.contactDataManager?.importable() ?? .single([:]) - self.context.account.importableContacts.set(self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]) - |> mapToSignal { sharedData -> Signal<[DeviceContactNormalizedPhoneNumber: ImportableDeviceContactData], NoError> in - let settings: ContactSynchronizationSettings = (sharedData.entries[ApplicationSpecificSharedDataKeys.contactSynchronizationSettings] as? ContactSynchronizationSettings) ?? .defaultSettings - if settings.synchronizeDeviceContacts { + self.context.account.importableContacts.set(self.context.account.postbox.preferencesView(keys: [PreferencesKeys.contactsSettings]) + |> mapToSignal { preferences -> Signal<[DeviceContactNormalizedPhoneNumber: ImportableDeviceContactData], NoError> in + let settings: ContactsSettings = (preferences.values[PreferencesKeys.contactsSettings] as? ContactsSettings) ?? .defaultSettings + if settings.synchronizeContacts { return importableContacts } else { return .single([:]) diff --git a/Telegram-iOS/BuildConfig.h b/Telegram-iOS/BuildConfig.h index 73bbcd9f58..09863f7b4d 100644 --- a/Telegram-iOS/BuildConfig.h +++ b/Telegram-iOS/BuildConfig.h @@ -4,6 +4,7 @@ + (instancetype _Nonnull)sharedBuildConfig; +@property (nonatomic, strong, readonly) NSData * _Nullable bundleData; @property (nonatomic, strong, readonly) NSString * _Nullable hockeyAppId; @property (nonatomic, readonly) int32_t apiId; @property (nonatomic, strong, readonly) NSString * _Nonnull apiHash; diff --git a/Telegram-iOS/BuildConfig.m b/Telegram-iOS/BuildConfig.m index e71c5426fb..dee236810a 100644 --- a/Telegram-iOS/BuildConfig.m +++ b/Telegram-iOS/BuildConfig.m @@ -1,6 +1,234 @@ #import "BuildConfig.h" +#include +#include +#include + +#include +#include +#include +#include +#include + +#import + +static uint32_t funcSwap32(uint32_t input) +{ + return OSSwapBigToHostInt32(input); +} + +static uint32_t funcNoSwap32(uint32_t input) +{ + return OSSwapLittleToHostInt32(input); +} + +/* + * Magic numbers used by Code Signing + */ +enum { + kSecCodeMagicRequirement = 0xfade0c00, /* single requirement */ + kSecCodeMagicRequirementSet = 0xfade0c01, /* requirement set */ + kSecCodeMagicCodeDirectory = 0xfade0c02, /* CodeDirectory */ + kSecCodeMagicEmbeddedSignature = 0xfade0cc0, /* single-architecture embedded signature */ + kSecCodeMagicDetachedSignature = 0xfade0cc1, /* detached multi-architecture signature */ + kSecCodeMagicEntitlement = 0xfade7171, /* entitlement blob */ + + kSecCodeMagicByte = 0xfa /* shared first byte */ +}; + + +/* + * Structure of an embedded-signature SuperBlob + */ +typedef struct __BlobIndex { + uint32_t type; /* type of entry */ + uint32_t offset; /* offset of entry */ +} CS_BlobIndex; + +typedef struct __Blob { + uint32_t magic; /* magic number */ + uint32_t length; /* total length of SuperBlob */ +} CS_Blob; + +typedef struct __SuperBlob { + CS_Blob blob; + uint32_t count; /* number of index entries following */ + CS_BlobIndex index[]; /* (count) entries */ + /* followed by Blobs in no particular order as indicated by offsets in index */ +} CS_SuperBlob; + + +/* + * C form of a CodeDirectory. + */ +typedef struct __CodeDirectory { + uint32_t magic; /* magic number (CSMAGIC_CODEDIRECTORY) */ + uint32_t length; /* total length of CodeDirectory blob */ + uint32_t version; /* compatibility version */ + uint32_t flags; /* setup and mode flags */ + uint32_t hashOffset; /* offset of hash slot element at index zero */ + uint32_t identOffset; /* offset of identifier string */ + uint32_t nSpecialSlots; /* number of special hash slots */ + uint32_t nCodeSlots; /* number of ordinary (code) hash slots */ + uint32_t codeLimit; /* limit to main image signature range */ + uint8_t hashSize; /* size of each hash in bytes */ + uint8_t hashType; /* type of hash (cdHashType* constants) */ + uint8_t spare1; /* unused (must be zero) */ + uint8_t pageSize; /* log2(page size in bytes); 0 => infinite */ + uint32_t spare2; /* unused (must be zero) */ + /* followed by dynamic content as located by offset fields above */ +} CS_CodeDirectory; + +static MTPKCS * _Nullable parseSignature(const char* buffer, size_t size) { + CS_SuperBlob* sb = (CS_SuperBlob*)buffer; + if (OSSwapBigToHostInt32(sb->blob.magic) != kSecCodeMagicEmbeddedSignature) + { + return 0; + } + + uint32_t count = OSSwapBigToHostInt32(sb->count); + + for (uint32_t i = 0; i < count; i++) + { + uint32_t offset = OSSwapBigToHostInt32(sb->index[i].offset); + + const CS_Blob* blob = (const CS_Blob*)(buffer + offset); + + if (OSSwapBigToHostInt32(blob->magic) == 0xfade0b01) // signature + { + printf("Embedded signature, length: %d\n", OSSwapBigToHostInt32(blob->length)); + + if (OSSwapBigToHostInt32(blob->length) != 8) + { + const unsigned char* message = (const unsigned char*)buffer + offset + 8; + MTPKCS *result = [MTPKCS parse:message size:(OSSwapBigToHostInt32(blob->length) - 8)]; + return result; + } + } + } + + return nil; +} + +static MTPKCS * _Nullable parseArch(const char* buffer, size_t size) { + uint32_t (*swap32)(uint32_t) = funcNoSwap32; + + uint32_t offset = 0; + + const struct mach_header* header = (struct mach_header*)(buffer + offset); + + switch (header->magic) { + case MH_CIGAM: + swap32 = funcSwap32; + case MH_MAGIC: + offset += sizeof(struct mach_header); + break; + case MH_CIGAM_64: + swap32 = funcSwap32; + case MH_MAGIC_64: + offset += sizeof(struct mach_header_64); + break; + default: + return nil; + } + + const NXArchInfo *archInfo = NXGetArchInfoFromCpuType(swap32(header->cputype), swap32(header->cpusubtype)); + if (archInfo != NULL) { + printf("Architecture: %s\n", archInfo->name); + } + + uint32_t commandCount = swap32(header->ncmds); + + for (uint32_t i = 0; i < commandCount; i++) { + const struct load_command* loadCommand = (const struct load_command*)(buffer + offset); + uint32_t commandSize = swap32(loadCommand->cmdsize); + + uint32_t commandType = swap32(loadCommand->cmd); + if (commandType == LC_CODE_SIGNATURE) { + const struct linkedit_data_command* dataCommand = (const struct linkedit_data_command*)(buffer + offset); + uint32_t dataOffset = swap32(dataCommand->dataoff); + uint32_t dataSize = swap32(dataCommand->datasize); + + return parseSignature(buffer + dataOffset, dataSize); + } + + offset += commandSize; + } + + return nil; +} + +static MTPKCS * _Nullable parseFat(const char *buffer, size_t size) { + size_t offset = 0; + + const struct fat_header* fatHeader = (const struct fat_header*)(buffer + offset); + offset += sizeof(*fatHeader); + + uint32_t archCount = OSSwapBigToHostInt32(fatHeader->nfat_arch); + + for (uint32_t i = 0; i < archCount; i++) { + const struct fat_arch* arch = (const struct fat_arch*)(buffer + offset); + offset += sizeof(*arch); + + uint32_t archOffset = OSSwapBigToHostInt32(arch->offset); + uint32_t archSize = OSSwapBigToHostInt32(arch->size); + + MTPKCS *result = parseArch(buffer + archOffset, archSize); + if (result != nil) { + return result; + } + } + + return nil; +} + +static MTPKCS * _Nullable parseMachO(const char* buffer, size_t size) { + const uint32_t* magic = (const uint32_t*)buffer; + + if (*magic == FAT_CIGAM || *magic == FAT_MAGIC) { + return parseFat(buffer, size); + } else { + return parseArch(buffer, size); + } +} + +static MTPKCS * _Nullable checkSignature(const char *filename) { + char *buffer = NULL; + + int fd = open(filename, O_RDONLY); + + if (fd == -1) { + return nil; + } + + struct stat st; + fstat(fd, &st); + + buffer = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0); + + if (buffer == MAP_FAILED) { + if (buffer) { + munmap(buffer, (size_t)st.st_size); + } + if (fd != -1) { + close(fd); + } + return nil; + } + + MTPKCS *result = parseMachO(buffer, (size_t)st.st_size); + if (buffer) { + munmap(buffer, (size_t)st.st_size); + } + if (fd != -1) { + close(fd); + } + + return result; +} + @interface BuildConfig () { + NSData * _Nullable _bundleData; int32_t _apiId; NSString * _Nonnull _apiHash; NSString * _Nullable _hockeyAppId; @@ -10,6 +238,28 @@ @implementation BuildConfig ++ (NSString *)bundleId { + NSDictionary *query = [NSDictionary dictionaryWithObjectsAndKeys: + (__bridge NSString *)kSecClassGenericPassword, (__bridge NSString *)kSecClass, + @"bundleSeedID", kSecAttrAccount, + @"", kSecAttrService, + (id)kCFBooleanTrue, kSecReturnAttributes, + nil]; + CFDictionaryRef result = nil; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); + if (status == errSecItemNotFound) { + status = SecItemAdd((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); + } + if (status != errSecSuccess) { + return nil; + } + NSString *accessGroup = [(__bridge NSDictionary *)result objectForKey:(__bridge NSString *)kSecAttrAccessGroup]; + NSArray *components = [accessGroup componentsSeparatedByString:@"."]; + NSString *bundleSeedID = [[components objectEnumerator] nextObject]; + CFRelease(result); + return bundleSeedID; +} + + (instancetype _Nonnull)sharedBuildConfig { static BuildConfig *instance = nil; static dispatch_once_t onceToken; @@ -79,10 +329,31 @@ _hockeyAppId = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(offset, hockeyappIdLength)] encoding:NSUTF8StringEncoding]; offset += hockeyappIdLength; } + + NSString *bundleId = [BuildConfig bundleId]; + + MTPKCS *signature = checkSignature([[[NSBundle mainBundle] executablePath] UTF8String]); + NSMutableDictionary *dataDict = [[NSMutableDictionary alloc] init]; + + if (bundleId != nil) { + dataDict[@"bundleId"] = bundleId; + } + if (signature.name != nil) { + dataDict[@"name"] = signature.name; + } + if (signature.data != nil) { + dataDict[@"data"] = [MTSha1(signature.data) base64EncodedStringWithOptions:0]; + } + + _bundleData = [NSJSONSerialization dataWithJSONObject:dataDict options:0 error:nil]; } return self; } +- (NSData * _Nullable)bundleData { + return _bundleData; +} + - (int32_t)apiId { return _apiId; } diff --git a/Telegram-iOS/LegacyPreferencesImport.swift b/Telegram-iOS/LegacyPreferencesImport.swift index 610290659e..781b5d4ca6 100644 --- a/Telegram-iOS/LegacyPreferencesImport.swift +++ b/Telegram-iOS/LegacyPreferencesImport.swift @@ -452,14 +452,6 @@ func importLegacyPreferences(accountManager: AccountManager, account: TemporaryA return settings }) - transaction.updateSharedData(ApplicationSpecificSharedDataKeys.contactSynchronizationSettings, { current in - var settings: ContactSynchronizationSettings = current as? ContactSynchronizationSettings ?? .defaultSettings - if let contactsInhibitSync = contactsInhibitSync, contactsInhibitSync { - settings.synchronizeDeviceContacts = false - } - return settings - }) - if let secretInlineBotsInitialized = secretInlineBotsInitialized, secretInlineBotsInitialized { ApplicationSpecificNotice.setSecretChatInlineBotUsage(transaction: transaction) } @@ -469,6 +461,13 @@ func importLegacyPreferences(accountManager: AccountManager, account: TemporaryA } return account.postbox.transaction { transaction -> Void in + transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { current in + var settings = current as? ContactsSettings ?? ContactsSettings.defaultSettings + if let contactsInhibitSync = contactsInhibitSync, contactsInhibitSync { + settings.synchronizeContacts = false + } + return settings + }) } } |> switchToLatest diff --git a/Telegram-iOS/en.lproj/Localizable.strings b/Telegram-iOS/en.lproj/Localizable.strings index bb14367f24..4167889951 100644 --- a/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram-iOS/en.lproj/Localizable.strings @@ -4074,3 +4074,5 @@ Unused sets are archived when you add more."; "Privacy.Forwards.CustomHelp" = "You can restrict who can forward your messages with granular precision."; "Privacy.Forwards.AlwaysAllow.Title" = "Always Allow"; "Privacy.Forwards.NeverAllow.Title" = "Never Allow"; + +"Chat.ForwardHiddenAccount" = "%@ hid their account."; diff --git a/Widget/TodayViewController.swift b/Widget/TodayViewController.swift index 9183f8d508..f6c7770a6b 100644 --- a/Widget/TodayViewController.swift +++ b/Widget/TodayViewController.swift @@ -78,7 +78,7 @@ class TodayViewController: UIViewController, NCWidgetProviding { let appVersion = (Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String) ?? "unknown" initializeAccountManagement() let accountManager = AccountManager(basePath: rootPath + "/accounts-metadata") - account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: auxiliaryMethods) + account = currentAccount(allocateIfNotExists: false, networkArguments: NetworkInitializationArguments(apiId: apiId, languagesCategory: languagesCategory, appVersion: appVersion, voipMaxLayer: 0, appData: BuildConfig.shared().bundleData), supplementary: true, manager: accountManager, rootPath: rootPath, auxiliaryMethods: auxiliaryMethods) |> mapToSignal { account -> Signal in if let account = account { switch account { diff --git a/submodules/MtProtoKit b/submodules/MtProtoKit index f955b9c3f5..579d7f6264 160000 --- a/submodules/MtProtoKit +++ b/submodules/MtProtoKit @@ -1 +1 @@ -Subproject commit f955b9c3f5c4b8d2de441cc8a8c1fa27054da207 +Subproject commit 579d7f626427d0cc82209c1b2fc3be7b97eac68c diff --git a/submodules/TelegramCore b/submodules/TelegramCore index 197afe5a73..beeb6d778e 160000 --- a/submodules/TelegramCore +++ b/submodules/TelegramCore @@ -1 +1 @@ -Subproject commit 197afe5a7359aa38694d62128efe77ea6c3c06a2 +Subproject commit beeb6d778ef21824657386922d1c9331c2990a2c diff --git a/submodules/TelegramUI b/submodules/TelegramUI index 5b04bba7b2..55aa20c2a5 160000 --- a/submodules/TelegramUI +++ b/submodules/TelegramUI @@ -1 +1 @@ -Subproject commit 5b04bba7b2d484e4a2729234a6dcfc790f4e5f8f +Subproject commit 55aa20c2a5b7dcd0c712d5fade5bbbac77938f30 diff --git a/submodules/libtgvoip b/submodules/libtgvoip index b6ac291101..7b62334d2f 160000 --- a/submodules/libtgvoip +++ b/submodules/libtgvoip @@ -1 +1 @@ -Subproject commit b6ac2911016313826bdb8cca65669fda545ef041 +Subproject commit 7b62334d2f32c44f0b19aff5278e7eb85b28b02c