From 7df923c4749dec7f45f8c505295b3ae8ecb8384f Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 28 Oct 2016 17:09:24 +0200 Subject: [PATCH 1/5] Crypto: Add Settings > LABS > End-to-End Encryption --- Vector/Assets/en.lproj/Vector.strings | 2 + .../ViewController/SettingsViewController.m | 75 +++++++++++++------ 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index 0ca4bad3b..b53d9f6a7 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -245,6 +245,8 @@ "settings_contacts_discover_matrix_users_with_local_emails" = "Use emails to discover users"; +"settings_labs_e2e_encryption" = "End-to-End Encryption"; + "settings_version" = "Version %@"; "settings_copyright" = "Copyright"; "settings_copyright_url" = "https://riot.im/copyright"; diff --git a/Vector/ViewController/SettingsViewController.m b/Vector/ViewController/SettingsViewController.m index d3ea44531..80a40a5b3 100644 --- a/Vector/ViewController/SettingsViewController.m +++ b/Vector/ViewController/SettingsViewController.m @@ -27,31 +27,20 @@ #import #import +enum { + SETTINGS_SECTION_SIGN_OUT_INDEX = 0, + SETTINGS_SECTION_USER_SETTINGS_INDEX, + SETTINGS_SECTION_NOTIFICATIONS_SETTINGS_INDEX, + SETTINGS_SECTION_IGNORED_USERS_INDEX, + SETTINGS_SECTION_CONTACTS_INDEX, + SETTINGS_SECTION_ADVANCED_INDEX, + SETTINGS_SECTION_OTHER_INDEX, #ifdef MX_USE_CONTACTS_SERVER_SYNC - -#define SETTINGS_SECTION_SIGN_OUT_INDEX 0 -#define SETTINGS_SECTION_USER_SETTINGS_INDEX 1 -#define SETTINGS_SECTION_NOTIFICATIONS_SETTINGS_INDEX 2 -#define SETTINGS_SECTION_IGNORED_USERS_INDEX 3 -#define SETTINGS_SECTION_CONTACTS_INDEX 4 -#define SETTINGS_SECTION_ADVANCED_INDEX 5 -#define SETTINGS_SECTION_OTHER_INDEX 6 -#define SETTINGS_SECTION_LABS_INDEX 7 -#define SETTINGS_SECTION_COUNT 7 // Not 8 because the LABS section is currently hidden - -#else - -#define SETTINGS_SECTION_SIGN_OUT_INDEX 0 -#define SETTINGS_SECTION_USER_SETTINGS_INDEX 1 -#define SETTINGS_SECTION_NOTIFICATIONS_SETTINGS_INDEX 2 -#define SETTINGS_SECTION_IGNORED_USERS_INDEX 3 -#define SETTINGS_SECTION_ADVANCED_INDEX 4 -#define SETTINGS_SECTION_OTHER_INDEX 5 -#define SETTINGS_SECTION_CONTACTS_INDEX 6 -#define SETTINGS_SECTION_LABS_INDEX 7 -#define SETTINGS_SECTION_COUNT 6 // Not 8 because the CONTACTS and LABS section is currently hidden - + SETTINGS_SECTION_CONTACTS_INDEX, #endif + SETTINGS_SECTION_LABS_INDEX, + SETTINGS_SECTION_COUNT +}; #define NOTIFICATION_SETTINGS_ENABLE_PUSH_INDEX 0 #define NOTIFICATION_SETTINGS_GLOBAL_SETTINGS_INDEX 1 @@ -76,7 +65,8 @@ #define OTHER_CLEAR_CACHE_INDEX 7 #define OTHER_COUNT 8 -#define LABS_COUNT 0 +#define LABS_CONFERENCE_CALL_INDEX 0 +#define LABS_COUNT 1 #define SECTION_TITLE_PADDING_WHEN_HIDDEN 0.01f @@ -1061,6 +1051,20 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); } else if (section == SETTINGS_SECTION_LABS_INDEX) { + if (row == LABS_CONFERENCE_CALL_INDEX) + { + MXSession* session = [[AppDelegate theDelegate].mxSessions objectAtIndex:0]; + + MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; + + labelAndSwitchCell.mxkLabel.text = NSLocalizedStringFromTable(@"settings_labs_e2e_encryption", @"Vector", nil); + labelAndSwitchCell.mxkSwitch.on = (nil != session.crypto); + + [labelAndSwitchCell.mxkSwitch removeTarget:self action:nil forControlEvents:UIControlEventTouchUpInside]; + [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleLabsEndToEndEncryption:) forControlEvents:UIControlEventTouchUpInside]; + + cell = labelAndSwitchCell; + } } return cell; @@ -1387,6 +1391,29 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); } } +- (void)toggleLabsEndToEndEncryption:(id)sender +{ + if (sender && [sender isKindOfClass:UISwitch.class]) + { + UISwitch *switchButton = (UISwitch*)sender; + + [self startActivityIndicator]; + + MXSession* session = [[AppDelegate theDelegate].mxSessions objectAtIndex:0]; + [session enableCrypto:switchButton.isOn success:^{ + + [self stopActivityIndicator]; + + } failure:^(NSError *error) { + + [self stopActivityIndicator]; + + // Come back to previous state button + [switchButton setOn:!switchButton.isOn animated:YES]; + }]; + } +} + - (void)markAllAsRead:(id)sender { // Feedback: disable button and run activity indicator From f8a609aacb45477267e6daf8c0767cc7b8aa1a46 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 2 Nov 2016 14:42:17 +0100 Subject: [PATCH 2/5] Crypto: strings for enabling crypto in a room. The button is coming --- Vector/Assets/en.lproj/Vector.strings | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index b53d9f6a7..891205a07 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -300,6 +300,8 @@ "room_details_banned_users_section"="Banned users"; "room_details_advanced_section"="Advanced"; "room_details_advanced_room_id"="Room ID:"; +"room_details_advanced_enable_e2e_encryption"="Enable encryption (warning: cannot be disabled again!)"; +"room_details_advanced_e2e_encryption_enabled"="Encryption is enabled in this room"; "room_details_fail_to_update_avatar" = "Fail to update the room photo"; "room_details_fail_to_update_room_name" = "Fail to update the room name"; "room_details_fail_to_update_topic" = "Fail to update the topic"; From 8cdcbadb40cb8bb91a4202a7ecafbe4fd71b71c9 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 3 Nov 2016 11:57:08 +0100 Subject: [PATCH 3/5] Crypto: RoomSettings: Add encryption switch button --- Vector/Assets/en.lproj/Vector.strings | 1 + .../RoomSettingsViewController.m | 143 +++++++++++++++--- 2 files changed, 126 insertions(+), 18 deletions(-) diff --git a/Vector/Assets/en.lproj/Vector.strings b/Vector/Assets/en.lproj/Vector.strings index 891205a07..edfe7f2ed 100644 --- a/Vector/Assets/en.lproj/Vector.strings +++ b/Vector/Assets/en.lproj/Vector.strings @@ -312,6 +312,7 @@ "room_details_fail_to_add_room_aliases" = "Fail to add the new room addresses"; "room_details_fail_to_remove_room_aliases" = "Fail to remove the room addresses"; "room_details_fail_to_update_room_canonical_alias" = "Fail to update the main address"; +"room_details_fail_to_enable_encryption" = "Fail to enable encryption in this room"; "room_details_save_changes_prompt" = "Do you want to save changes?"; "room_details_set_main_address" = "Set as Main Address"; "room_details_unset_main_address" = "Unset as Main Address"; diff --git a/Vector/ViewController/RoomSettingsViewController.m b/Vector/ViewController/RoomSettingsViewController.m index 2c67c9b22..afb73acc8 100644 --- a/Vector/ViewController/RoomSettingsViewController.m +++ b/Vector/ViewController/RoomSettingsViewController.m @@ -78,6 +78,7 @@ NSString *const kRoomSettingsHistoryVisibilityKey = @"kRoomSettingsHistoryVisibi NSString *const kRoomSettingsNewAliasesKey = @"kRoomSettingsNewAliasesKey"; NSString *const kRoomSettingsRemovedAliasesKey = @"kRoomSettingsRemovedAliasesKey"; NSString *const kRoomSettingsCanonicalAliasKey = @"kRoomSettingsCanonicalAliasKey"; +NSString *const kRoomSettingsEncryptionKey = @"kRoomSettingsEncryptionKey"; NSString *const kRoomSettingsNameCellViewIdentifier = @"kRoomSettingsNameCellViewIdentifier"; NSString *const kRoomSettingsTopicCellViewIdentifier = @"kRoomSettingsTopicCellViewIdentifier"; @@ -85,6 +86,8 @@ NSString *const kRoomSettingsWarningCellViewIdentifier = @"kRoomSettingsWarningC NSString *const kRoomSettingsNewAddressCellViewIdentifier = @"kRoomSettingsNewAddressCellViewIdentifier"; NSString *const kRoomSettingsAddressCellViewIdentifier = @"kRoomSettingsAddressCellViewIdentifier"; NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvancedCellViewIdentifier"; +NSString *const kRoomSettingsAdvancedEnableE2eCellViewIdentifier = @"kRoomSettingsAdvancedEnableE2eCellViewIdentifier"; +NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSettingsAdvancedE2eEnabledCellViewIdentifier"; @interface RoomSettingsViewController () { @@ -136,7 +139,8 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance // switches UISwitch *roomNotifSwitch; - + UISwitch *roomEncryptionSwitch; + // Observe kAppDelegateDidTapStatusBarNotification to handle tap on clock status bar. id appDelegateDidTapStatusBarNotificationObserver; @@ -1580,6 +1584,48 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance return; } + + // Room encryption + if ([updatedItemsDict objectForKey:kRoomSettingsEncryptionKey]) + { + pendingOperation = [mxRoom enableEncryptionWithAlgorithm:kMXCryptoMegolmAlgorithm success:^{ + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + + [strongSelf->updatedItemsDict removeObjectForKey:kRoomSettingsEncryptionKey]; + [strongSelf onSave:nil]; + } + + } failure:^(NSError *error) { + + NSLog(@"[RoomSettingsViewController] Enabling encrytion failed. Error: %@", error); + + if (weakSelf) + { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf->pendingOperation = nil; + + dispatch_async(dispatch_get_main_queue(), ^{ + + NSString* message = error.localizedDescription; + if (!message.length) + { + message = NSLocalizedStringFromTable(@"room_details_fail_to_enable_encryption", @"Vector", nil); + } + [strongSelf onSaveFailed:message withKey:kRoomSettingsEncryptionKey]; + + }); + } + + }]; + + return; + } } [self getNavigationItem].rightBarButtonItem.enabled = NO; @@ -1693,6 +1739,11 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance else if (section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) { count = 1; + + if (mxRoom.mxSession.crypto) + { + count++; + } } return count; @@ -2000,7 +2051,14 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance directoryToggleCell.mxkLabel.textColor = kVectorTextColorBlack; directoryVisibilitySwitch = directoryToggleCell.mxkSwitch; - + + // Workaround to avoid mixing between switches + // TODO: this is a design issue with switch within UITableViewCell that must fix everywhere + if (roomEncryptionSwitch == directoryVisibilitySwitch) + { + roomEncryptionSwitch = nil; + } + [directoryVisibilitySwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged]; directoryVisibilitySwitch.onTintColor = kVectorColorGreen; @@ -2243,24 +2301,70 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance } else if (indexPath.section == ROOM_SETTINGS_ADVANCED_SECTION_INDEX) { - cell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsAdvancedCellViewIdentifier]; - if (!cell) + if (indexPath.row == 0) { - cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kRoomSettingsAdvancedCellViewIdentifier]; + cell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsAdvancedCellViewIdentifier]; + if (!cell) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kRoomSettingsAdvancedCellViewIdentifier]; + } + + cell.textLabel.font = [UIFont systemFontOfSize:17]; + cell.textLabel.text = NSLocalizedStringFromTable(@"room_details_advanced_room_id", @"Vector", nil); + cell.textLabel.textColor = kVectorTextColorBlack; + + cell.detailTextLabel.font = [UIFont systemFontOfSize:15]; + cell.detailTextLabel.text = mxRoomState.roomId; + cell.detailTextLabel.textColor = kVectorTextColorGray; + cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } + else if (indexPath.row == 1) + { + if (mxRoom.state.isEncrypted) + { + cell = [tableView dequeueReusableCellWithIdentifier:kRoomSettingsAdvancedE2eEnabledCellViewIdentifier]; + if (!cell) + { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kRoomSettingsAdvancedE2eEnabledCellViewIdentifier]; + } + + cell.textLabel.font = [UIFont systemFontOfSize:17]; + cell.textLabel.text = NSLocalizedStringFromTable(@"room_details_advanced_e2e_encryption_enabled", @"Vector", nil); + cell.textLabel.textColor = kVectorTextColorBlack; + + cell.selectionStyle = UITableViewCellSelectionStyleNone; + } + else + { + MXKTableViewCellWithLabelAndSwitch *roomEncryptionCell = [tableView dequeueReusableCellWithIdentifier:[MXKTableViewCellWithLabelAndSwitch defaultReuseIdentifier] forIndexPath:indexPath]; + + roomEncryptionCell.mxkLabelLeadingConstraint.constant = roomEncryptionCell.separatorInset.left; + roomEncryptionCell.mxkSwitchTrailingConstraint.constant = 15; + + [roomEncryptionCell.mxkSwitch addTarget:self action:@selector(onSwitchUpdate:) forControlEvents:UIControlEventValueChanged]; + roomEncryptionCell.mxkSwitch.onTintColor = kVectorColorGreen; + + roomEncryptionCell.mxkLabel.text = NSLocalizedStringFromTable(@"room_details_advanced_enable_e2e_encryption", @"Vector", nil); + roomEncryptionCell.mxkLabel.textColor = kVectorTextColorBlack; + + roomEncryptionSwitch = roomEncryptionCell.mxkSwitch; + + // Workaround to avoid mixing between switches + // TODO: this is a design issue with switch within UITableViewCell that must fix everywhere + if (directoryVisibilitySwitch == roomEncryptionSwitch) + { + directoryVisibilitySwitch = nil; + } + + roomEncryptionSwitch.on = [updatedItemsDict objectForKey:kRoomSettingsEncryptionKey]; + + cell = roomEncryptionCell; + } } - - cell.textLabel.font = [UIFont systemFontOfSize:17]; - cell.textLabel.text = NSLocalizedStringFromTable(@"room_details_advanced_room_id", @"Vector", nil); - cell.textLabel.textColor = kVectorTextColorBlack; - - cell.detailTextLabel.font = [UIFont systemFontOfSize:15]; - cell.detailTextLabel.text = mxRoomState.roomId; - cell.detailTextLabel.textColor = kVectorTextColorGray; - cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - - cell.selectionStyle = UITableViewCellSelectionStyleNone; } - + // Sanity check if (!cell) { @@ -2815,7 +2919,10 @@ NSString *const kRoomSettingsAdvancedCellViewIdentifier = @"kRoomSettingsAdvance [updatedItemsDict setObject:visibility forKey:kRoomSettingsDirectoryKey]; } } - + else if (theSwitch == roomEncryptionSwitch) + { + [updatedItemsDict setObject:[NSNumber numberWithBool:roomEncryptionSwitch.on] forKey:kRoomSettingsEncryptionKey]; + } [self getNavigationItem].rightBarButtonItem.enabled = (updatedItemsDict.count != 0); } From 9568fa3ebae60e6b3421a4ff63894e746332e5f4 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 3 Nov 2016 14:03:55 +0100 Subject: [PATCH 4/5] Crypto: Prepare Podfile for crypto but this is commented for now --- Podfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Podfile b/Podfile index baeb44062..a475e31b7 100644 --- a/Podfile +++ b/Podfile @@ -29,5 +29,10 @@ pod 'GoogleAnalytics' # The Google WebRTC stack pod 'WebRTC', '13869.6.0' +# OLMKit for crypto +#pod 'OLMKit' +#pod 'OLMKit', :git => 'https://matrix.org/git/olm.git', :branch => 'olmkit' +#pod 'OLMKit', :path => '../olm/OLMKit.podspec' + end From 5c71c927bcf13bf2dafd90fe0e642005a73d7ca6 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 3 Nov 2016 15:29:04 +0100 Subject: [PATCH 5/5] Crypto: Fix naming in SettingsViewController --- Vector/ViewController/SettingsViewController.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Vector/ViewController/SettingsViewController.m b/Vector/ViewController/SettingsViewController.m index 80a40a5b3..1c996d4f0 100644 --- a/Vector/ViewController/SettingsViewController.m +++ b/Vector/ViewController/SettingsViewController.m @@ -65,7 +65,7 @@ enum { #define OTHER_CLEAR_CACHE_INDEX 7 #define OTHER_COUNT 8 -#define LABS_CONFERENCE_CALL_INDEX 0 +#define LABS_CRYPTO_INDEX 0 #define LABS_COUNT 1 #define SECTION_TITLE_PADDING_WHEN_HIDDEN 0.01f @@ -1051,7 +1051,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); } else if (section == SETTINGS_SECTION_LABS_INDEX) { - if (row == LABS_CONFERENCE_CALL_INDEX) + if (row == LABS_CRYPTO_INDEX) { MXSession* session = [[AppDelegate theDelegate].mxSessions objectAtIndex:0];