123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2016-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- #import "MDMSetup.h"
- #import "LicenseStore.h"
- #import "UserSettings.h"
- #import "MyIdentityStore.h"
- #import "ServerAPIConnector.h"
- #import "ValidationLogger.h"
- #import <ThreemaFramework/ThreemaFramework-Swift.h>
- #ifdef DEBUG
- static const DDLogLevel ddLogLevel = DDLogLevelAll;
- #else
- static const DDLogLevel ddLogLevel = DDLogLevelNotice;
- #endif
- NSString * const MDM_CONFIGURATION_KEY = @"com.apple.configuration.managed"; // Company MDM persists in user defaults
- NSString * const MDM_FEEDBACK_KEY = @"com.apple.feedback.managed";
- NSString * const MDM_THREEMA_CONFIGURATION_KEY = @"threema_mdm_configuration"; // Threema MDM persists in user defaults
- NSString * const MDM_KEY_LICENSE_USERNAME = @"th_license_username"; // String
- NSString * const MDM_KEY_LICENSE_PASSWORD = @"th_license_password"; // String
- NSString * const MDM_KEY_NICKNAME = @"th_nickname"; // String max 32
- NSString * const MDM_KEY_LINKED_EMAIL = @"th_linked_email"; // String
- NSString * const MDM_KEY_LINKED_PHONE = @"th_linked_phone"; // String
- NSString * const MDM_KEY_FIRST_NAME = @"th_firstname"; // String
- NSString * const MDM_KEY_LAST_NAME = @"th_lastname"; // String
- NSString * const MDM_KEY_CSI = @"th_csi"; // String
- NSString * const MDM_KEY_CATEGORY = @"th_category"; // String
- NSString * const MDM_KEY_CONTACT_SYNC = @"th_contact_sync"; // Bool
- NSString * const MDM_KEY_READONLY_PROFILE = @"th_readonly_profile"; // Bool
- NSString * const MDM_KEY_ID_BACKUP = @"th_id_backup"; // String
- NSString * const MDM_KEY_ID_BACKUP_PASSWORD = @"th_id_backup_password"; // String
- NSString * const MDM_KEY_BLOCK_UNKNOWN = @"th_block_unknown"; // Bool
- NSString * const MDM_KEY_HIDE_INACTIVE_IDS = @"th_hide_inactive_ids"; // Bool
- NSString * const MDM_KEY_DISABLE_SAVE_TO_GALLERY = @"th_disable_save_to_gallery"; // Bool
- NSString * const MDM_KEY_DISABLE_ADD_CONTACT = @"th_disable_add_contact"; // Bool
- NSString * const MDM_KEY_DISABLE_EXPORT = @"th_disable_export"; // Bool
- NSString * const MDM_KEY_DISABLE_BACKUPS = @"th_disable_backups"; // Bool
- NSString * const MDM_KEY_DISABLE_ID_EXPORT = @"th_disable_id_export"; // Bool
- NSString * const MDM_KEY_DISABLE_SYSTEM_BACKUPS = @"th_disable_system_backups"; // Bool
- NSString * const MDM_KEY_DISABLE_MESSAGE_PREVIEW = @"th_disable_message_preview"; // Bool
- NSString * const MDM_KEY_DISABLE_SEND_PROFILE_PICTURE = @"th_disable_send_profile_picture"; // Bool
- NSString * const MDM_KEY_DISABLE_CALLS = @"th_disable_calls"; // Bool
- NSString * const MDM_KEY_DISABLE_VIDEO_CALLS = @"th_disable_video_calls"; // String
- NSString * const MDM_KEY_DISABLE_CREATE_GROUP = @"th_disable_create_group"; // Bool
- NSString * const MDM_KEY_SKIP_WIZARD = @"th_skip_wizard"; // Bool
- NSString * const MDM_KEY_DISABLE_WEB = @"th_disable_web"; // Bool
- NSString * const MDM_KEY_WEB_HOSTS = @"th_web_hosts"; // String
- NSString * const MDM_KEY_DISABLE_SHARE_MEDIA = @"th_disable_share_media"; // Bool
- NSString * const MDM_KEY_SAFE_ENABLE = @"th_safe_enable"; // Bool
- NSString * const MDM_KEY_SAFE_PASSWORD = @"th_safe_password"; // String min. 8, max. 4096
- NSString * const MDM_KEY_SAFE_SERVER_URL = @"th_safe_server_url"; // String
- NSString * const MDM_KEY_SAFE_SERVER_USERNAME = @"th_safe_server_username"; // String
- NSString * const MDM_KEY_SAFE_SERVER_PASSWORD = @"th_safe_server_password"; // String
- NSString * const MDM_KEY_SAFE_RESTORE_ENABLE = @"th_safe_restore_enable"; // Bool
- NSString * const MDM_KEY_SAFE_RESTORE_ID = @"th_safe_restore_id"; // String 8
- NSString * const MDM_KEY_SAFE_PASSWORD_PATTERN = @"th_safe_password_pattern"; // String
- NSString * const MDM_KEY_SAFE_PASSWORD_MESSAGE = @"th_safe_password_message"; // String
- NSString * const MDM_KEY_THREEMA_CONFIGURATION = @"mdm";
- NSString * const MDM_KEY_THREEMA_OVERRIDE = @"override";
- NSString * const MDM_KEY_THREEMA_PARAMS = @"params";
- static NSDictionary *_mdmCache;
- static NSDictionary *_mdmCacheSetup;
- @implementation MDMSetup
- - (MDMSetup*)initWithSetup:(BOOL)setup {
- self = [super init];
- if (self) {
- isSetup = setup;
- isLicenseRequired = [[LicenseStore sharedLicenseStore] getRequiresLicenseKey] == YES;
-
- queue = dispatch_queue_create("ch.threema.MdmConfiguration", NULL);
- }
- return self;
- }
- + (void)clearMdmCache {
- _mdmCache = nil;
- _mdmCacheSetup = nil;
- }
- // MARK: MDM values
- - (BOOL)disableBackups {
- NSNumber *disableBackups = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_BACKUPS];
- return [disableBackups isKindOfClass:[NSNumber class]] ? disableBackups.boolValue : NO;
- }
- - (BOOL)disableIdExport {
- NSNumber *disableIdExport = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_ID_EXPORT];
- return [disableIdExport isKindOfClass:[NSNumber class]] ? disableIdExport.boolValue : NO;
- }
- - (BOOL)disableSystemBackups {
- NSNumber *disableSystemBackups = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_SYSTEM_BACKUPS];
- return [disableSystemBackups isKindOfClass:[NSNumber class]] ? disableSystemBackups.boolValue : NO;
- }
- - (BOOL)readonlyProfile {
- NSNumber *readonlyProfile = [self getMdmConfigurationBoolForKey:MDM_KEY_READONLY_PROFILE];
- return [readonlyProfile isKindOfClass:[NSNumber class]] ? readonlyProfile.boolValue : NO;
- }
- - (BOOL)disableAddContact {
- NSNumber *disableAddContact = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_ADD_CONTACT];
- return [disableAddContact isKindOfClass:[NSNumber class]] ? disableAddContact.boolValue : NO;
- }
- - (BOOL)disableSaveToGallery {
- NSNumber *disableSaveToGallery = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_SAVE_TO_GALLERY];
- return [disableSaveToGallery isKindOfClass:[NSNumber class]] ? disableSaveToGallery.boolValue : NO;
- }
- - (BOOL)disableExport {
- NSNumber *disableExport = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_EXPORT];
- return [disableExport isKindOfClass:[NSNumber class]] ? disableExport.boolValue : NO;
- }
- - (BOOL)disableMessagePreview {
- NSNumber *disableMessagePreview = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_MESSAGE_PREVIEW];
- return [disableMessagePreview isKindOfClass:[NSNumber class]] ? disableMessagePreview.boolValue : NO;
- }
- - (BOOL)disableCalls {
- NSNumber *disableCalls = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_CALLS];
- return [disableCalls isKindOfClass:[NSNumber class]] ? disableCalls.boolValue : NO;
- }
- - (BOOL)disableVideoCalls {
- NSNumber *disableVideoCalls = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_VIDEO_CALLS];
- return [disableVideoCalls isKindOfClass:[NSNumber class]] ? disableVideoCalls.boolValue : NO;
- }
- - (BOOL)disableWeb {
- NSNumber *disableWeb = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_WEB];
- return [disableWeb isKindOfClass:[NSNumber class]] ? disableWeb.boolValue : NO;
- }
- - (NSString *)webHosts {
- NSString *webHosts = [self getMdmConfigurationValueForKey:MDM_KEY_WEB_HOSTS];
- return [webHosts isKindOfClass:[NSString class]] ? webHosts : nil;
- }
- - (BOOL)disableCreateGroup {
- NSNumber *disableCreateGroup = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_CREATE_GROUP];
- return [disableCreateGroup isKindOfClass:[NSNumber class]] ? disableCreateGroup.boolValue : NO;
- }
- - (BOOL)disableSendProfilePicture {
- NSNumber *disableSendProfilePicture = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_SEND_PROFILE_PICTURE];
- return [disableSendProfilePicture isKindOfClass:[NSNumber class]] ? disableSendProfilePicture.boolValue : NO;
- }
- - (BOOL)skipWizard {
- NSNumber *skipWizard = [self getMdmConfigurationBoolForKey:MDM_KEY_SKIP_WIZARD];
- return [skipWizard isKindOfClass:[NSNumber class]] ? skipWizard.boolValue : NO;
- }
- - (BOOL)disableShareMedia {
- NSNumber *disableShareMedia = [self getMdmConfigurationBoolForKey:MDM_KEY_DISABLE_SHARE_MEDIA];
- return [disableShareMedia isKindOfClass:[NSNumber class]] ? disableShareMedia.boolValue : NO;
- }
- - (BOOL)disableHideStaleContacts {
- NSNumber *disableHideInactiveIds = [self getMdmConfigurationBoolForKey:MDM_KEY_HIDE_INACTIVE_IDS];
- return [disableHideInactiveIds isKindOfClass:[NSNumber class]] ? YES : NO;
- }
- - (NSNumber*)safeEnable {
- NSNumber *safeEnable = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_ENABLE];
- return [safeEnable isKindOfClass:[NSNumber class]] ? safeEnable : nil;
- }
- - (NSString*)safePassword {
- NSString *safePassword = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_PASSWORD];
- return [safePassword isKindOfClass:[NSString class]] ? safePassword : nil;
- }
- - (NSString*)safeServerUrl {
- NSString *safeServerUrl = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_SERVER_URL];
- return [safeServerUrl isKindOfClass:[NSString class]] ? safeServerUrl : nil;
- }
- - (NSString*)safeServerUsername {
- NSString *safeServerUsername = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_SERVER_USERNAME];
- return [safeServerUsername isKindOfClass:[NSString class]] ? safeServerUsername : nil;
- }
- - (NSString*)safeServerPassword {
- NSString *safeServerPassword = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_SERVER_PASSWORD];
- return [safeServerPassword isKindOfClass:[NSString class]] ? safeServerPassword : nil;
- }
- - (BOOL)safeRestoreEnable {
- NSNumber *safeRestoreEnable = [self getMdmConfigurationBoolForKey:MDM_KEY_SAFE_RESTORE_ENABLE];
- return [safeRestoreEnable isKindOfClass:[NSNumber class]] ? safeRestoreEnable.boolValue : YES;
- }
- - (NSString*)safeRestoreId {
- NSString *safeRestoreId = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_RESTORE_ID];
- return [safeRestoreId isKindOfClass:[NSString class]] ? safeRestoreId : nil;
- }
- - (NSString *)safePasswordPattern {
- NSString *safePasswordPattern = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_PASSWORD_PATTERN];
- return [safePasswordPattern isKindOfClass:[NSString class]] ? safePasswordPattern : nil;
- }
- - (NSString *)safePasswordMessage {
- NSString *safePasswordMessage = [self getMdmConfigurationValueForKey:MDM_KEY_SAFE_PASSWORD_MESSAGE];
- return [safePasswordMessage isKindOfClass:[NSString class]] ? safePasswordMessage : nil;
- }
- // MARK: Threema Safe status
- - (BOOL)isSafeBackupDisable {
- return [[self safeSetupWork] isSafeBackupStatusSetWithSafeState:SafeSetupWork.backupDisable];
- }
- - (BOOL)isSafeBackupForce {
- return [[self safeSetupWork] isSafeBackupStatusSetWithSafeState:SafeSetupWork.backupForce];
- }
- - (BOOL)isSafeBackupPasswordPreset {
- return [[self safeSetupWork] isSafeBackupStatusSetWithSafeState:SafeSetupWork.passwordPreset];
- }
- - (BOOL)isSafeBackupServerPreset {
- return [[self safeSetupWork] isSafeBackupStatusSetWithSafeState:SafeSetupWork.serverPreset];
- }
- - (BOOL)isSafeRestoreDisable {
- return [[self safeSetupWork] isSafeRestoreStatusSetWithSafeState:SafeSetupWork.restoreDisable];
- }
- - (BOOL)isSafeRestoreForce {
- return [[self safeSetupWork] isSafeRestoreStatusSetWithSafeState:SafeSetupWork.restoreForce];
- }
- - (BOOL)isSafeRestorePasswordPreset {
- return [[self safeSetupWork] isSafeRestoreStatusSetWithSafeState:SafeSetupWork.passwordPreset];
- }
- - (BOOL)isSafeRestoreServerPreset {
- return [[self safeSetupWork] isSafeRestoreStatusSetWithSafeState:SafeSetupWork.serverPreset];
- }
- - (SafeSetupWork*)safeSetupWork {
- return [[SafeSetupWork alloc] initWithMdmSetup:self];
- }
- // MARK: apply MDM to user settings, identity
- - (void)loadRenewableValues {
- if (![self isManaged]) {
- return;
- }
- [self loadLicenseInfo];
-
- UserSettings *userSettings = [UserSettings sharedUserSettings];
- NSNumber *blockUnknown = [self getMdmConfigurationBoolForKey:MDM_KEY_BLOCK_UNKNOWN];
- if ([blockUnknown isKindOfClass:[NSNumber class]]) {
- userSettings.blockUnknown = blockUnknown.boolValue;
- }
-
- NSNumber *hideInactiveIds = [self getMdmConfigurationBoolForKey:MDM_KEY_HIDE_INACTIVE_IDS];
- if ([hideInactiveIds isKindOfClass:[NSNumber class]]) {
- userSettings.hideStaleContacts = hideInactiveIds.boolValue;
- }
-
- NSNumber *contactSync = [self getMdmConfigurationBoolForKey:MDM_KEY_CONTACT_SYNC];
- if ([contactSync isKindOfClass:[NSNumber class]]) {
- userSettings.syncContacts = contactSync.boolValue;
- }
-
- if ([self existsMdmKey:MDM_KEY_DISABLE_SAVE_TO_GALLERY]) {
- userSettings.autoSaveMedia = ![self disableSaveToGallery];
- }
-
- if ([self existsMdmKey:MDM_KEY_DISABLE_MESSAGE_PREVIEW]) {
- userSettings.pushDecrypt = ![self disableMessagePreview];
- }
-
- if ([self existsMdmKey:MDM_KEY_DISABLE_CALLS]) {
- userSettings.enableThreemaCall = ![self disableCalls];
- }
-
- if ([self existsMdmKey:MDM_KEY_DISABLE_VIDEO_CALLS]) {
- userSettings.enableVideoCall= ![self disableVideoCalls];
- }
-
- if ([self existsMdmKey:MDM_KEY_DISABLE_SEND_PROFILE_PICTURE]) {
- if ([self disableSendProfilePicture]) {
- [userSettings setSendProfilePicture:SendProfilePictureNone];
- }
- }
- }
- - (void)loadLicenseInfo {
- if (![self isManaged]) {
- return;
- }
-
- NSString *licenseUsername = [self getMdmConfigurationValueForKey:MDM_KEY_LICENSE_USERNAME];
- if ([licenseUsername isKindOfClass:[NSString class]] && licenseUsername.length > 0) {
- [LicenseStore sharedLicenseStore].licenseUsername = licenseUsername;
- }
-
- NSString *licensePassword = [self getMdmConfigurationValueForKey:MDM_KEY_LICENSE_PASSWORD];
- if ([licensePassword isKindOfClass:[NSString class]] && licensePassword.length > 0) {
- [LicenseStore sharedLicenseStore].licensePassword = licensePassword;
- }
- }
- - (void)loadIDCreationValues {
- if (![self isManaged]) {
- return;
- }
-
- MyIdentityStore *identityStore = [MyIdentityStore sharedMyIdentityStore];
- NSString *nickname = [self getMdmConfigurationValueForKey:MDM_KEY_NICKNAME];
- if ([nickname isKindOfClass:[NSString class]] && nickname.length > 0 && nickname.length < 32) {
- identityStore.pushFromName = nickname;
- }
-
- NSNumber *contactSync = [self getMdmConfigurationBoolForKey:MDM_KEY_CONTACT_SYNC];
- if ([contactSync isKindOfClass:[NSNumber class]]) {
- [UserSettings sharedUserSettings].syncContacts = contactSync.boolValue;
- }
-
- NSString *email = [self getMdmConfigurationValueForKey:MDM_KEY_LINKED_EMAIL];
- if ([email isKindOfClass:[NSString class]] && email.length > 0) {
- identityStore.createIDEmail = email;
- }
-
- NSString *phone = [self getMdmConfigurationValueForKey:MDM_KEY_LINKED_PHONE];
- if ([phone isKindOfClass:[NSString class]] && phone.length > 0) {
- identityStore.createIDPhone = phone;
- }
-
- NSString *firstName = [self getMdmConfigurationValueForKey:MDM_KEY_FIRST_NAME];
- if ([firstName isKindOfClass:[NSString class]]) {
- identityStore.firstName = firstName;
- }
-
- NSString *lastName = [self getMdmConfigurationValueForKey:MDM_KEY_LAST_NAME];
- if ([lastName isKindOfClass:[NSString class]]) {
- identityStore.lastName = lastName;
- }
-
- NSString *csi = [self getMdmConfigurationValueForKey:MDM_KEY_CSI];
- if ([csi isKindOfClass:[NSString class]]) {
- identityStore.csi = csi;
- }
-
- NSString *category = [self getMdmConfigurationValueForKey:MDM_KEY_CATEGORY];
- if ([category isKindOfClass:[NSString class]]) {
- identityStore.category = category;
- }
-
- [[LicenseStore sharedLicenseStore] performUpdateWorkInfo];
- }
- - (BOOL)hasIDBackup {
- if (![self isManaged]) {
- return NO;
- }
-
- _idBackup = [self getMdmConfigurationValueForKey:MDM_KEY_ID_BACKUP];
- if ([_idBackup isKindOfClass:[NSString class]] == NO || _idBackup.length < 1) {
- return NO;
- }
-
- _idBackupPassword = [self getMdmConfigurationValueForKey:MDM_KEY_ID_BACKUP_PASSWORD];
-
- return YES;
- }
- - (void)restoreIDBackupOnCompletion:(void(^)(void))onCompletion onError:(void(^)(NSError *error))onError {
- if ([self hasIDBackup] == NO) {
- return;
- }
-
- MyIdentityStore *identityStore = [MyIdentityStore sharedMyIdentityStore];
- identityStore.pendingCreateID = YES;
-
- [identityStore restoreFromBackup:_idBackup withPassword:_idBackupPassword onCompletion:^{
- ServerAPIConnector *apiConnector = [[ServerAPIConnector alloc] init];
- /* Obtain server group from server */
- [apiConnector updateMyIdentityStore:identityStore onCompletion:^{
- [identityStore storeInKeychain];
- onCompletion();
- } onError:^(NSError *error) {
- onError(error);
- }];
- } onError:^(NSError *error) {
- onError(error);
- }];
- }
- - (BOOL)isManaged {
- NSDictionary *mdm = [self getMdmConfiguration];
- return isLicenseRequired && mdm != nil && [mdm count] > 0;
- }
- - (BOOL)existsMdmKey:(NSString*)mdmKey {
- NSDictionary *mdm = [self getMdmConfiguration];
- return [[mdm allKeys] containsObject:mdmKey];
- }
- /// Apply Threema MDM parameters (workData) to company MDM
- - (void)applyThreemaMdm:(NSDictionary *)workData {
- if (!isLicenseRequired) {
- return;
- }
-
- dispatch_sync(queue, ^{
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- if (workData != nil && [[workData allKeys] containsObject:MDM_KEY_THREEMA_CONFIGURATION]) {
- NSDictionary *threemaMdm = [defaults dictionaryForKey:MDM_THREEMA_CONFIGURATION_KEY];
-
- NSDictionary *newThreemaMdm = workData[MDM_KEY_THREEMA_CONFIGURATION];
- NSMutableDictionary *currentThreemaMdm = [[NSMutableDictionary alloc] initWithDictionary:threemaMdm];
-
- if (currentThreemaMdm == nil || [currentThreemaMdm count] == 0) {
- // use new Threema MDM
- threemaMdm = newThreemaMdm;
- } else if([currentThreemaMdm isEqualToDictionary:newThreemaMdm] == NO) {
- // remove missing Threema MDM parameters
- NSMutableArray *missingMdmKeys = [[NSMutableArray alloc] init];
- NSMutableDictionary *currentThreemaMdmParameters = [[NSMutableDictionary alloc] initWithDictionary:currentThreemaMdm[MDM_KEY_THREEMA_PARAMS]];
- [currentThreemaMdmParameters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
- if ([[newThreemaMdm[MDM_KEY_THREEMA_PARAMS] allKeys] containsObject:key] == NO) {
- [missingMdmKeys addObject:key];
- }
- }];
- [currentThreemaMdmParameters removeObjectsForKeys:missingMdmKeys];
- [currentThreemaMdm setObject:currentThreemaMdmParameters forKey:MDM_KEY_THREEMA_PARAMS];
-
- // apply new Threema MDM parameters
- BOOL override = ((NSNumber *)newThreemaMdm[MDM_KEY_THREEMA_OVERRIDE]).boolValue;
- NSDictionary *newThreemaMdmParameters = [self applyMdmParameters:currentThreemaMdm[MDM_KEY_THREEMA_PARAMS] source:newThreemaMdm[MDM_KEY_THREEMA_PARAMS] override:override];
-
- NSMutableDictionary *newThreemaMdmConfiguration = [[NSMutableDictionary alloc] initWithDictionary:threemaMdm];
- [newThreemaMdmConfiguration setObject:newThreemaMdmParameters forKey:MDM_KEY_THREEMA_PARAMS];
- [newThreemaMdmConfiguration setObject:[NSNumber numberWithBool:override] forKey:MDM_KEY_THREEMA_OVERRIDE];
- threemaMdm = newThreemaMdmConfiguration;
- }
-
- // store Threema MDM
- [defaults setObject:threemaMdm forKey:MDM_THREEMA_CONFIGURATION_KEY];
- [defaults synchronize];
- } else {
- [defaults removeObjectForKey:MDM_THREEMA_CONFIGURATION_KEY];
- [defaults synchronize];
- }
- [MDMSetup clearMdmCache];
- });
- [self loadIDCreationValues];
- [self loadRenewableValues];
- }
- - (NSDictionary*)getMdmCompany {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- return [defaults dictionaryForKey:MDM_CONFIGURATION_KEY];
-
- /// fake company MDM parameters here
- // NSDictionary *companyMdm = [[NSDictionary alloc] initWithObjectsAndKeys:@1, MDM_KEY_READONLY_PROFILE, @"123456", MDM_KEY_LICENSE_PASSWORD, @"po", MDM_KEY_LICENSE_USERNAME, @"test@test.ch", MDM_KEY_LINKED_EMAIL, @"+41791112233", MDM_KEY_LINKED_PHONE, @"id_pass", MDM_KEY_ID_BACKUP_PASSWORD, @"safe_pass", MDM_KEY_SAFE_PASSWORD, @"server_pass", MDM_KEY_SAFE_SERVER_PASSWORD, @0, MDM_KEY_DISABLE_VIDEO_CALLS, nil];
- // return companyMdm;
- }
- - (NSDictionary*)getMdmConfiguration {
- __block NSDictionary *mdm;
- dispatch_sync(queue, ^{
- if (isLicenseRequired) {
- if (!isSetup) {
- if (_mdmCache == nil) {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- _mdmCache = [self getMdmParameters:[self getMdmCompany] threemMdm:[defaults dictionaryForKey:MDM_THREEMA_CONFIGURATION_KEY]];
- }
- mdm = _mdmCache;
- } else {
- if (_mdmCacheSetup == nil) {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- _mdmCacheSetup = [self getMdmParameters:[self getMdmCompany] threemMdm:[defaults dictionaryForKey:MDM_THREEMA_CONFIGURATION_KEY]];
- }
- mdm = _mdmCacheSetup;
- }
- } else {
- mdm = [[NSDictionary alloc] init];
- }
- });
- return mdm;
- }
- - (NSDictionary*)getMdmParameters:(NSDictionary*)companyMdm threemMdm:(NSDictionary*)threemaMdm {
- if (companyMdm != nil) {
- if (threemaMdm != nil) {
- // merge company and Threema MDM
- BOOL override = ((NSNumber *)threemaMdm[MDM_KEY_THREEMA_OVERRIDE]).boolValue;
- NSDictionary *newMdm = [self applyMdmParameters:companyMdm source:threemaMdm[MDM_KEY_THREEMA_PARAMS] override:override];
- DDLogNotice(@"\nCompany MDM");
- [self printMDMIntoDebugLog:companyMdm];
-
- DDLogNotice(@"\nThreema MDM");
- [self printMDMIntoDebugLog:threemaMdm];
-
- DDLogNotice(@"\nMerged Company and Threema MDM");
- [self printMDMIntoDebugLog:newMdm];
- return newMdm;
- } else {
- // use Company MDM
- DDLogNotice(@"\nCompany MDM");
- [self printMDMIntoDebugLog:companyMdm];
- return companyMdm;
- }
- } else if (threemaMdm != nil && [[threemaMdm allKeys] containsObject:MDM_KEY_THREEMA_PARAMS]) {
- // use Threema MDM
- NSDictionary *destinationMdm = [[NSDictionary alloc] init];
- BOOL override = ((NSNumber *)threemaMdm[MDM_KEY_THREEMA_OVERRIDE]).boolValue;
- NSDictionary *newMdm = [self applyMdmParameters:destinationMdm source:threemaMdm[MDM_KEY_THREEMA_PARAMS] override:override];
-
- DDLogNotice(@"\nThreema MDM");
- [self printMDMIntoDebugLog:newMdm];
-
- return newMdm;
-
- }
-
- // print empty mdm
- DDLogNotice(@"\nCompany and Threema MDM is empty");
- return [[NSDictionary alloc] init];
- }
- - (NSDictionary*)applyMdmParameters:(NSDictionary*)destination source:(NSDictionary*)source override:(BOOL)override {
- NSMutableDictionary *mdmParameters = [[NSMutableDictionary alloc] initWithDictionary:destination];
-
- // apply parameter if is override and renweable or missing
- [[source allKeys] enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL * _Nonnull stop) {
- if (override == YES && [self isRenewable:key]) {
- if ([[mdmParameters allKeys] containsObject:key]) {
- [mdmParameters setValue:source[key] forKey:key];
- } else {
- [mdmParameters addEntriesFromDictionary:@{key: source[key]}];
- }
- }
- if (isSetup == YES && [[mdmParameters allKeys] containsObject:key] == NO) {
- [mdmParameters addEntriesFromDictionary:@{key: source[key]}];
- }
- else if (isSetup == YES && override == YES && [[mdmParameters allKeys] containsObject:key] == YES) {
- [mdmParameters setValue:source[key] forKey:key];
- }
- }];
-
- return mdmParameters;
- }
- - (void)deleteThreemaMdm {
- dispatch_sync(queue, ^{
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults removeObjectForKey:MDM_THREEMA_CONFIGURATION_KEY];
- [defaults synchronize];
-
- [MDMSetup clearMdmCache];
- });
- }
- - (BOOL)isRenewable:(NSString *)mdmKey {
- NSArray *renewableKeys = @[MDM_KEY_LICENSE_USERNAME, MDM_KEY_LICENSE_PASSWORD, MDM_KEY_NICKNAME, MDM_KEY_FIRST_NAME, MDM_KEY_LAST_NAME, MDM_KEY_CSI, MDM_KEY_CATEGORY, MDM_KEY_READONLY_PROFILE, MDM_KEY_BLOCK_UNKNOWN, MDM_KEY_HIDE_INACTIVE_IDS, MDM_KEY_DISABLE_SAVE_TO_GALLERY, MDM_KEY_DISABLE_ADD_CONTACT, MDM_KEY_DISABLE_EXPORT, MDM_KEY_DISABLE_BACKUPS, MDM_KEY_DISABLE_ID_EXPORT, MDM_KEY_DISABLE_SYSTEM_BACKUPS, MDM_KEY_DISABLE_MESSAGE_PREVIEW, MDM_KEY_DISABLE_SEND_PROFILE_PICTURE, MDM_KEY_DISABLE_CALLS, MDM_KEY_DISABLE_CREATE_GROUP, MDM_KEY_DISABLE_WEB, MDM_KEY_WEB_HOSTS, MDM_KEY_SAFE_ENABLE, MDM_KEY_SAFE_PASSWORD, MDM_KEY_SAFE_SERVER_URL, MDM_KEY_SAFE_SERVER_USERNAME, MDM_KEY_SAFE_SERVER_PASSWORD, MDM_KEY_SAFE_PASSWORD_PATTERN, MDM_KEY_SAFE_PASSWORD_MESSAGE, MDM_KEY_DISABLE_SHARE_MEDIA, MDM_KEY_CONTACT_SYNC, MDM_KEY_DISABLE_VIDEO_CALLS];
- return [renewableKeys containsObject:mdmKey];
- }
- - (NSNumber*)getMdmConfigurationBoolForKey:(NSString*)key {
- // Some MDMs cannot send real booleans, so we support "true"/"1" and "false"/"0" as strings also
- id mdmVal = [self getMdmConfigurationValueForKey:key];
- if ([mdmVal isKindOfClass:[NSNumber class]]) {
- return mdmVal;
- } else if ([mdmVal isKindOfClass:[NSString class]]) {
- if ([mdmVal caseInsensitiveCompare:@"true"] == NSOrderedSame || [mdmVal isEqualToString:@"1"]) {
- return [NSNumber numberWithBool:YES];
- } else if ([mdmVal caseInsensitiveCompare:@"false"] == NSOrderedSame || [mdmVal isEqualToString:@"0"]) {
- return [NSNumber numberWithBool:NO];
- }
- }
- return nil;
- }
- - (id)getMdmConfigurationValueForKey:(NSString*)key {
- NSDictionary *mdm = [self getMdmConfiguration];
- return mdm[key];
- }
- - (void)printMDMIntoDebugLog:(NSDictionary *)mdm {
- if ([[mdm allKeys] containsObject:MDM_KEY_THREEMA_PARAMS]) {
- BOOL override = ((NSNumber *)mdm[MDM_KEY_THREEMA_OVERRIDE]).boolValue;
- DDLogNotice(@"%@: %@", MDM_KEY_THREEMA_OVERRIDE, override ? @"true" : @"false");
-
- for(NSString *key in mdm[MDM_KEY_THREEMA_PARAMS]) {
- [self checkIsPasswordAndLog:key value:[mdm[MDM_KEY_THREEMA_PARAMS] objectForKey:key]];
- }
- } else {
- for(NSString *key in mdm) {
- [self checkIsPasswordAndLog:key value:[mdm objectForKey:key]];
- }
- }
- }
- - (void)checkIsPasswordAndLog:(NSString *)key value:(NSString *)value {
- if (![key containsString:@"pass"] || [key isEqualToString:MDM_KEY_SAFE_PASSWORD_PATTERN] || [key isEqualToString:MDM_KEY_SAFE_PASSWORD_MESSAGE] || value == nil) {
- DDLogNotice(@"%@: %@", key, value);
- } else {
- DDLogNotice(@"%@: ***", key);
- }
- }
- @end
|