IdentityKeyStore changes

1) Always accept keys from incoming messages

2) Block sending only if it's a recent change, or if always
   block is enabled

// FREEBIE

// FREEBIE
This commit is contained in:
Michael Kirk 2017-05-23 08:28:12 -07:00
parent 4851e43047
commit bb25d2beb6
23 changed files with 267 additions and 102 deletions

View File

@ -3,10 +3,10 @@ source 'https://github.com/CocoaPods/Specs.git'
target 'Signal' do
pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git'
pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git'
#pod 'AxolotlKit', path: '../SignalProtocolKit'
pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git'
#pod 'SignalServiceKit', path: '../SignalServiceKit'
#pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git'
pod 'AxolotlKit', path: '../SignalProtocolKit'
#pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git'
pod 'SignalServiceKit', path: '../SignalServiceKit'
pod 'OpenSSL'
pod 'JSQMessagesViewController', git: 'https://github.com/WhisperSystems/JSQMessagesViewController.git', branch: 'mkirk/position-edit-menu'
#pod 'JSQMessagesViewController' path: '../JSQMessagesViewController'

View File

@ -109,35 +109,29 @@ PODS:
- YapDatabase/SQLCipher/Core
DEPENDENCIES:
- AxolotlKit (from `https://github.com/WhisperSystems/SignalProtocolKit.git`)
- AxolotlKit (from `../SignalProtocolKit`)
- JSQMessagesViewController (from `https://github.com/WhisperSystems/JSQMessagesViewController.git`, branch `mkirk/position-edit-menu`)
- OpenSSL
- PureLayout
- Reachability
- SignalServiceKit (from `https://github.com/WhisperSystems/SignalServiceKit.git`)
- SignalServiceKit (from `../SignalServiceKit`)
- SocketRocket (from `https://github.com/facebook/SocketRocket.git`)
EXTERNAL SOURCES:
AxolotlKit:
:git: https://github.com/WhisperSystems/SignalProtocolKit.git
:path: "../SignalProtocolKit"
JSQMessagesViewController:
:branch: mkirk/position-edit-menu
:git: https://github.com/WhisperSystems/JSQMessagesViewController.git
SignalServiceKit:
:git: https://github.com/WhisperSystems/SignalServiceKit.git
:path: "../SignalServiceKit"
SocketRocket:
:git: https://github.com/facebook/SocketRocket.git
CHECKOUT OPTIONS:
AxolotlKit:
:commit: bce663486ac34c70594deae8260b3cd29dd086e9
:git: https://github.com/WhisperSystems/SignalProtocolKit.git
JSQMessagesViewController:
:commit: 7054e4b13ee5bcd6d524adb6dc9a726e8c466308
:git: https://github.com/WhisperSystems/JSQMessagesViewController.git
SignalServiceKit:
:commit: 0a8c4203ead4e283e930236e37f243c022af5c07
:git: https://github.com/WhisperSystems/SignalServiceKit.git
SocketRocket:
:commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf
:git: https://github.com/facebook/SocketRocket.git
@ -164,6 +158,6 @@ SPEC CHECKSUMS:
UnionFind: c33be5adb12983981d6e827ea94fc7f9e370f52d
YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266
PODFILE CHECKSUM: 48e80d7f1e049bbf544a689fdfdf33e8196c640a
PODFILE CHECKSUM: dc5ed308ade575a81ccadf5c485990530353c4ee
COCOAPODS: 1.2.1

View File

@ -141,12 +141,14 @@
45847E871E4283C30080EAB3 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45847E861E4283C30080EAB3 /* Intents.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */; };
45855F381D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */; };
4585C4601ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4585C45F1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m */; };
458967111DC117CC00E9DD21 /* AccountManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 458967101DC117CC00E9DD21 /* AccountManagerTest.swift */; };
458DE9D61DEE3FD00071BB03 /* PeerConnectionClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 458DE9D51DEE3FD00071BB03 /* PeerConnectionClient.swift */; };
458DE9D91DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m in Sources */ = {isa = PBXBuildFile; fileRef = 458DE9D81DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m */; };
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */; };
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38391D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m */; };
459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */; };
459B1C671ED480BB00506A04 /* MarkIdentityAsSeenJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 459B1C661ED480BB00506A04 /* MarkIdentityAsSeenJob.swift */; };
45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; };
45A6DAD71EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; };
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
@ -553,6 +555,8 @@
45847E861E4283C30080EAB3 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
45855F351D9498A40084F340 /* OWSContactAvatarBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactAvatarBuilder.h; sourceTree = "<group>"; };
45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactAvatarBuilder.m; sourceTree = "<group>"; };
4585C45E1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWS104CreateRecipientIdentities.h; path = Migrations/OWS104CreateRecipientIdentities.h; sourceTree = "<group>"; };
4585C45F1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWS104CreateRecipientIdentities.m; path = Migrations/OWS104CreateRecipientIdentities.m; sourceTree = "<group>"; };
4589670F1DC117CC00E9DD21 /* SignalTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SignalTests-Bridging-Header.h"; sourceTree = "<group>"; };
458967101DC117CC00E9DD21 /* AccountManagerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AccountManagerTest.swift; path = Models/AccountManagerTest.swift; sourceTree = "<group>"; };
458DE9D51DEE3FD00071BB03 /* PeerConnectionClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerConnectionClient.swift; sourceTree = "<group>"; };
@ -565,6 +569,7 @@
459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDeviceTableViewCell.m; sourceTree = "<group>"; };
4597E94E1D8313C100040CDE /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = translations/sq.lproj/Localizable.strings; sourceTree = "<group>"; };
4597E94F1D8313CB00040CDE /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = translations/bg.lproj/Localizable.strings; sourceTree = "<group>"; };
459B1C661ED480BB00506A04 /* MarkIdentityAsSeenJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MarkIdentityAsSeenJob.swift; path = Jobs/MarkIdentityAsSeenJob.swift; sourceTree = "<group>"; };
45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = "<group>"; };
45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = "<group>"; };
45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; };
@ -1067,6 +1072,8 @@
45387B031E36D650005D00B3 /* OWS102MoveLoggingPreferenceToUserDefaults.m */,
450573FC1E78A06D00615BB4 /* OWS103EnableVideoCalling.h */,
450573FD1E78A06D00615BB4 /* OWS103EnableVideoCalling.m */,
4585C45E1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.h */,
4585C45F1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m */,
);
name = Migrations;
sourceTree = "<group>";
@ -1139,6 +1146,7 @@
451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */,
45D231761DC7E8F10034FA89 /* SessionResetJob.swift */,
452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */,
459B1C661ED480BB00506A04 /* MarkIdentityAsSeenJob.swift */,
);
name = Jobs;
sourceTree = "<group>";
@ -2085,6 +2093,7 @@
76EB062618170B33006006FC /* Queue.m in Sources */,
D221A09A169C9E5E00537ABF /* main.m in Sources */,
345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */,
4585C4601ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m in Sources */,
45843D1F1D2236B30013E85A /* OWSContactsSearcher.m in Sources */,
450873C31D9D5149006B54F2 /* OWSExpirationTimerView.m in Sources */,
B6258B331C29E2E60014138E /* NotificationsManager.m in Sources */,
@ -2105,6 +2114,7 @@
45C681C61D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.m in Sources */,
34F3089F1ECA580B00BB7697 /* OWSUnreadIndicatorCell.m in Sources */,
34B3F8861E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m in Sources */,
459B1C671ED480BB00506A04 /* MarkIdentityAsSeenJob.swift in Sources */,
452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */,
452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */,
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */,

View File

@ -28,7 +28,7 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "606C728DF011400A4DF4884E7704A3D9"
BlueprintIdentifier = "BAF5052C29D98877DA59C91BAE557FE2"
BuildableName = "libSignalServiceKit.a"
BlueprintName = "SignalServiceKit"
ReferencedContainer = "container:Pods/Pods.xcodeproj">

View File

@ -201,7 +201,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
[[TextSecureKitEnv alloc] initWithCallMessageHandler:[Environment getCurrent].callMessageHandler
contactsManager:[Environment getCurrent].contactsManager
messageSender:[Environment getCurrent].messageSender
notificationsManager:[Environment getCurrent].notificationsManager];
notificationsManager:[Environment getCurrent].notificationsManager
preferences:[Environment getCurrent].preferences];
[TextSecureKitEnv setSharedEnv:sharedEnv];
[[TSStorageManager sharedManager] setupDatabase];

View File

@ -0,0 +1,51 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import Foundation
@objc
class MarkIdentityAsSeenJob: NSObject {
let TAG = "[MarkIdentityAsSeenJob]"
private let thread: TSThread
public class func run(thread: TSThread) {
MarkIdentityAsSeenJob(thread: thread).run()
}
init(thread: TSThread) {
self.thread = thread
}
public func run() {
switch self.thread {
case let contactThread as TSContactThread:
markAsSeenIfNecessary(recipientId: contactThread.contactIdentifier())
case let groupThread as TSGroupThread:
groupThread.groupModel.groupMemberIds?.forEach { memberId in
guard let recipientId = memberId as? String else {
Logger.error("\(TAG) unexecpted type in group members.")
assertionFailure("\(TAG) unexecpted type in group members.")
return
}
markAsSeenIfNecessary(recipientId: recipientId)
}
default:
assertionFailure("Unexpected thread type: \(self.thread)")
}
}
private func markAsSeenIfNecessary(recipientId: String) {
guard let identity = OWSRecipientIdentity.fetch(uniqueId: recipientId) else {
Logger.verbose("\(TAG) no existing identity for recipient: \(recipientId). No messages with them yet?")
return
}
if !identity.wasSeen {
Logger.info("\(TAG) marking identity as seen for recipient: \(recipientId)")
identity.markAsSeen()
identity.save()
}
}
}

View File

@ -56,6 +56,7 @@
#import <SignalServiceKit/OWSGetMessagesRequest.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSOutgoingCallMessage.h>
#import <SignalServiceKit/OWSRecipientIdentity.h>
#import <SignalServiceKit/OWSSignalService.h>
#import <SignalServiceKit/OWSTurnServerInfoRequest.h>
#import <SignalServiceKit/PhoneNumber.h>
@ -68,6 +69,7 @@
#import <SignalServiceKit/TSCall.h>
#import <SignalServiceKit/TSContactThread.h>
#import <SignalServiceKit/TSErrorMessage.h>
#import <SignalServiceKit/TSGroupThread.h>
#import <SignalServiceKit/TSInfoMessage.h>
#import <SignalServiceKit/TSMessagesManager.h>
#import <SignalServiceKit/TSNetworkManager.h>

View File

@ -42,7 +42,11 @@ NS_ASSUME_NONNULL_BEGIN
addSection:[OWSTableSection
sectionWithTitle:@"Session State"
items:@[
[OWSTableItem itemWithTitle:@"Print all sessions"
[OWSTableItem itemWithTitle:@"Log All Recipient Identities"
actionBlock:^{
[OWSRecipientIdentity printAllIdentities];
}],
[OWSTableItem itemWithTitle:@"Log All Sessions"
actionBlock:^{
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[[TSStorageManager sharedManager] printAllSessions];
@ -76,7 +80,6 @@ NS_ASSUME_NONNULL_BEGIN
messageSender:[Environment getCurrent].messageSender
storageManager:[TSStorageManager sharedManager]];
}]
]]];
[contents addSection:[DebugUIContacts section]];

View File

@ -751,6 +751,7 @@ typedef enum : NSUInteger {
// all messages as read.
[self ensureThreadOffersAndIndicators];
// TODO: Why are we marking as read here? Shouldn't our repeating 1-sec read timer be sufficient?
[self markAllMessagesAsRead];
[self.uiDatabaseConnection beginLongLivedReadTransaction];
@ -1177,11 +1178,16 @@ typedef enum : NSUInteger {
- (void)startReadTimer {
self.readTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(markAllMessagesAsRead)
selector:@selector(readTimerDidFire)
userInfo:nil
repeats:YES];
}
- (void)readTimerDidFire
{
[self markAllMessagesAsRead];
}
- (void)cancelReadTimer {
[self.readTimer invalidate];
}
@ -1205,6 +1211,7 @@ typedef enum : NSUInteger {
_callOnOpen = NO;
}
[self updateNavigationBarSubtitleLabel];
[MarkIdentityAsSeenJob runWithThread:self.thread];
}
- (void)viewWillDisappear:(BOOL)animated {
@ -1523,6 +1530,8 @@ typedef enum : NSUInteger {
[[OWSFingerprintBuilder alloc] initWithStorageManager:self.storageManager contactsManager:self.contactsManager];
OWSFingerprint *fingerprint =
[builder fingerprintWithTheirSignalId:theirSignalId theirIdentityKey:theirIdentityKey];
// TODO: Why are we marking as read here? Shouldn't our repeating 1-sec read timer be sufficient?
[self markAllMessagesAsRead];
NSString *contactName = [self.contactsManager displayNameForPhoneIdentifier:theirSignalId];
@ -2552,11 +2561,31 @@ typedef enum : NSUInteger {
[self tappedUnknownContactBlockOfferMessage:(OWSUnknownContactBlockOfferMessage *)message];
} else if (message.errorType == TSErrorMessageInvalidMessage) {
[self tappedCorruptedMessage:message];
} else if (message.errorType == TSErrorMessageNonBlockingIdentityChange) {
[self tappedNonBlockingIdentityChangeForRecipientId:message.recipientId];
} else {
DDLogWarn(@"%@ Unhandled tap for error message:%@", self.tag, message);
}
}
- (void)tappedNonBlockingIdentityChangeForRecipientId:(NSString *)signalId
{
NSParameterAssert(signalId != nil);
OWSFingerprintBuilder *fingerprintBuilder =
[[OWSFingerprintBuilder alloc] initWithStorageManager:self.storageManager contactsManager:self.contactsManager];
OWSFingerprint *fingerprint = [fingerprintBuilder fingerprintWithTheirSignalId:signalId];
FingerprintViewController *fingerprintViewController =
[[UIStoryboard main] instantiateViewControllerWithIdentifier:@"FingerprintViewController"];
NSString *contactName = [self.contactsManager displayNameForPhoneIdentifier:signalId];
[fingerprintViewController configureWithThread:self.thread fingerprint:fingerprint contactName:contactName];
[self presentViewController:fingerprintViewController animated:YES completion:nil];
}
- (void)handleInfoMessageTap:(TSInfoMessage *)message
{
if ([message isKindOfClass:[OWSAddToContactsOfferMessage class]]) {

View File

@ -38,7 +38,7 @@ class OversizeTextMessageViewController: UIViewController {
assert(false)
return nil
}
guard let attachment = TSAttachment.fetch(withUniqueID:attachmentID) as? TSAttachmentStream else {
guard let attachment = TSAttachment.fetch(uniqueId: attachmentID) as? TSAttachmentStream else {
Logger.error("\(TAG) could not load attachment.")
assert(false)
return nil

View File

@ -18,7 +18,7 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
PrivacySettingsTableViewControllerSectionIndexCalling,
PrivacySettingsTableViewControllerSectionIndexCallKit,
PrivacySettingsTableViewControllerSectionIndexHistoryLog,
PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange,
PrivacySettingsTableViewControllerSectionIndexBlockSendingOnIdentityChange,
PrivacySettingsTableViewControllerSectionIndex_Count // meta section to track how many sections
};
@ -38,8 +38,8 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
@property (nonatomic) UITableViewCell *callsHideIPAddressCell;
@property (nonatomic) UISwitch *callsHideIPAddressSwitch;
@property (nonatomic, strong) UITableViewCell *blockOnIdentityChangeCell;
@property (nonatomic, strong) UISwitch *blockOnIdentityChangeSwitch;
@property (nonatomic, strong) UITableViewCell *sendingIdentityApprovalRequiredCell;
@property (nonatomic, strong) UISwitch *isSendingIdentityApprovalRequiredSwitch;
@property (nonatomic, strong) UITableViewCell *clearHistoryLogCell;
@ -116,16 +116,16 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
self.clearHistoryLogCell.textLabel.text = NSLocalizedString(@"SETTINGS_CLEAR_HISTORY", @"");
self.clearHistoryLogCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Block Identity on KeyChange
self.blockOnIdentityChangeCell = [UITableViewCell new];
self.blockOnIdentityChangeCell.textLabel.text
= NSLocalizedString(@"SETTINGS_BLOCK_ON_IDENTITY_CHANGE_TITLE", @"Table cell label");
self.blockOnIdentityChangeSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
self.blockOnIdentityChangeCell.accessoryView = self.blockOnIdentityChangeSwitch;
[self.blockOnIdentityChangeSwitch setOn:[Environment.preferences shouldBlockOnIdentityChange]];
[self.blockOnIdentityChangeSwitch addTarget:self
action:@selector(didToggleBlockOnIdentityChangeSwitch:)
forControlEvents:UIControlEventValueChanged];
// Block Sending on Key Change
self.sendingIdentityApprovalRequiredCell = [UITableViewCell new];
self.sendingIdentityApprovalRequiredCell.textLabel.text
= NSLocalizedString(@"SETTINGS_BLOCK_SENDING_ON_IDENTITY_CHANGE_TITLE", @"Table cell label");
self.isSendingIdentityApprovalRequiredSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
self.sendingIdentityApprovalRequiredCell.accessoryView = self.isSendingIdentityApprovalRequiredSwitch;
[self.isSendingIdentityApprovalRequiredSwitch setOn:[Environment.preferences isSendingIdentityApprovalRequired]];
[self.isSendingIdentityApprovalRequiredSwitch addTarget:self
action:@selector(didToggleisSendingIdentityApprovalRequiredSwitch:)
forControlEvents:UIControlEventValueChanged];
}
#pragma mark - Table view data source
@ -149,7 +149,7 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
return [Environment getCurrent].preferences.isCallKitEnabled ? 2 : 1;
case PrivacySettingsTableViewControllerSectionIndexHistoryLog:
return 1;
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
case PrivacySettingsTableViewControllerSectionIndexBlockSendingOnIdentityChange:
return 1;
default:
return 0;
@ -168,7 +168,7 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
return ([UIDevice currentDevice].supportsCallKit
? NSLocalizedString(@"SETTINGS_SECTION_CALL_KIT_DESCRIPTION", @"Settings table section footer.")
: nil);
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
case PrivacySettingsTableViewControllerSectionIndexBlockSendingOnIdentityChange:
return NSLocalizedString(
@"SETTINGS_BLOCK_ON_IDENITY_CHANGE_DETAIL", @"User settings section footer, a detailed explanation");
default:
@ -193,8 +193,8 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
}
case PrivacySettingsTableViewControllerSectionIndexHistoryLog:
return self.clearHistoryLogCell;
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
return self.blockOnIdentityChangeCell;
case PrivacySettingsTableViewControllerSectionIndexBlockSendingOnIdentityChange:
return self.sendingIdentityApprovalRequiredCell;
default: {
DDLogError(@"%@ Requested unknown table view cell for row at indexPath: %@", self.tag, indexPath);
return [UITableViewCell new];
@ -211,7 +211,7 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
return NSLocalizedString(@"SETTINGS_SECTION_TITLE_CALLING", @"settings topic header for table section");
case PrivacySettingsTableViewControllerSectionIndexHistoryLog:
return NSLocalizedString(@"SETTINGS_HISTORYLOG_TITLE", @"Section header");
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
case PrivacySettingsTableViewControllerSectionIndexBlockSendingOnIdentityChange:
return NSLocalizedString(@"SETTINGS_PRIVACY_VERIFICATION_TITLE", @"Section header");
default:
return nil;
@ -263,11 +263,11 @@ typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
[Environment.preferences setScreenSecurity:enabled];
}
- (void)didToggleBlockOnIdentityChangeSwitch:(UISwitch *)sender
- (void)didToggleisSendingIdentityApprovalRequiredSwitch:(UISwitch *)sender
{
BOOL enabled = self.blockOnIdentityChangeSwitch.isOn;
DDLogInfo(@"%@ toggled blockOnIdentityChange: %@", self.tag, enabled ? @"ON" : @"OFF");
[Environment.preferences setShouldBlockOnIdentityChange:enabled];
BOOL enabled = self.isSendingIdentityApprovalRequiredSwitch.isOn;
DDLogInfo(@"%@ toggled isSendingIdentityApprovalRequired: %@", self.tag, enabled ? @"ON" : @"OFF");
[Environment.preferences setIsSendingIdentityApprovalRequired:enabled];
}
- (void)didToggleCallsHideIPAddressSwitch:(UISwitch *)sender

View File

@ -362,7 +362,6 @@ class SystemContactsFetcher: NSObject {
AssertIsOnMainThread()
guard !systemContactsHaveBeenRequestedAtLeastOnce else {
Logger.debug("\(TAG) already requested system contacts")
completion?(nil)
return
}

View File

@ -32,7 +32,7 @@ class ExperienceUpgradeFinder: NSObject {
// MARK: - Instance Methods
public func allUnseen(transaction: YapDatabaseReadTransaction) -> [ExperienceUpgrade] {
return allExperienceUpgrades.filter { ExperienceUpgrade.fetch(withUniqueID: $0.uniqueId, transaction: transaction) == nil }
return allExperienceUpgrades.filter { ExperienceUpgrade.fetch(uniqueId: $0.uniqueId, transaction: transaction) == nil }
}
public func markAllAsSeen(transaction: YapDatabaseReadWriteTransaction) {

View File

@ -1,8 +1,8 @@
// Created by Michael Kirk on 11/8/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWS101ExistingUsersBlockOnIdentityChange.h"
#import <SignalServiceKit/TSPrivacyPreferences.h>
#import <YapDatabase/YapDatabaseTransaction.h>
NS_ASSUME_NONNULL_BEGIN
@ -19,10 +19,11 @@ static NSString *const OWS101ExistingUsersBlockOnIdentityChangeMigrationId = @"1
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
DDLogWarn(@"[OWS101ExistingUsersBlockOnIdentityChange] Opting existing user into 'blocking' on identity changes.");
TSPrivacyPreferences *preferences = [TSPrivacyPreferences sharedInstance];
preferences.shouldBlockOnIdentityChange = YES;
[preferences saveWithTransaction:transaction];
DDLogWarn(@"[OWS101ExistingUsersBlockOnIdentityChange] has been obviated.");
// DDLogWarn(@"[OWS101ExistingUsersBlockOnIdentityChange] Opting existing user into 'blocking' on identity
// changes."); TSPrivacyPreferences *preferences = [TSPrivacyPreferences sharedInstance];
// preferences.shouldBlockOnIdentityChange = YES;
// [preferences saveWithTransaction:transaction];
}
@end

View File

@ -0,0 +1,13 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSDatabaseMigration.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWS104CreateRecipientIdentities : OWSDatabaseMigration
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,77 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWS104CreateRecipientIdentities.h"
#import <SignalServiceKit/OWSRecipientIdentity.h>
#import <SignalServiceKit/TSStorageManager+IdentityKeyStore.h>
#import <YapDatabase/YapDatabaseConnection.h>
#import <YapDatabase/YapDatabaseTransaction.h>
NS_ASSUME_NONNULL_BEGIN
// Increment a similar constant for every future DBMigration
static NSString *const OWS104CreateRecipientIdentitiesMigrationId = @"104";
/**
* New SN behavaior requires tracking additional state - not just the identity key data.
* So we wrap the key, along with the new meta-data in an OWSRecipientIdentity.
*/
@implementation OWS104CreateRecipientIdentities
+ (NSString *)migrationId
{
return OWS104CreateRecipientIdentitiesMigrationId;
}
// Overriding runUp instead of runUpWithTransaction in order to implement a blocking migration.
- (void)runUp
{
[[OWSRecipientIdentity dbConnection] readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
NSMutableDictionary<NSString *, NSData *> *identityKeys = [NSMutableDictionary new];
[transaction
enumerateKeysAndObjectsInCollection:TSStorageManagerTrustedKeysCollection
usingBlock:^(
NSString *_Nonnull recipientId, id _Nonnull object, BOOL *_Nonnull stop) {
if (![object isKindOfClass:[NSData class]]) {
DDLogError(
@"%@ Unexpected object in trusted keys collection key: %@ object: %@",
self.tag,
recipientId,
object);
OWSAssert(NO);
return;
}
NSData *identityKey = (NSData *)object;
[identityKeys setObject:identityKey forKey:recipientId];
}];
[identityKeys enumerateKeysAndObjectsUsingBlock:^(
NSString *_Nonnull recipientId, NSData *_Nonnull identityKey, BOOL *_Nonnull stop) {
DDLogInfo(@"%@ Migrating identity key for recipient: %@", self.tag, recipientId);
[[[OWSRecipientIdentity alloc] initWithRecipientId:recipientId
identityKey:identityKey
isFirstKnownKey:NO
createdAt:[NSDate dateWithTimeIntervalSince1970:0]
approvedForBlockingUse:YES
approvedForNonBlockingUse:NO] saveWithTransaction:transaction];
}];
}];
}
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,5 +1,6 @@
// Created by Michael Kirk on 9/28/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#include <SignalServiceKit/TSYapDatabaseObject.h>
@ -13,20 +14,12 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) TSStorageManager *storageManager;
/**
* Run an asynchronous migration. Prefer this to the blocking variant whenever possible as the migration runner will
* block launching, and potentially crash apps e.g. if a view is being populated.
*/
// Prefer nonblocking (async) migrations by overriding `runUpWithTransaction:` in a subclass.
// Blocking migrations running too long will crash the app, effectively bricking install
// because the user will never get past it.
// If you must write a launch-blocking migration, override runUp.
- (void)runUp;
/**
* Run a synchronous migration.
* TODO: there's currently no tooling in the migration runner to run BlockingMigrations, as we don't have any yet.
* Try to avoid this whenever possible as the migration runner will block launching, and potentially crash apps
* e.g. if a view is being populated.
*/
- (void)runUpWithBlockingMigration;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,5 +1,6 @@
// Created by Michael Kirk on 9/28/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSDatabaseMigration.h"
#import <SignalServiceKit/TSStorageManager.h>
@ -63,19 +64,6 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
/**
* Try to avoid using this.
*/
- (void)runUpWithBlockingMigration
{
[self.storageManager.newDatabaseConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[self runUpWithTransaction:transaction];
}];
DDLogInfo(@"Completed migration %@", self.uniqueId);
[self save];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -4,9 +4,10 @@
#import "OWSDatabaseMigrationRunner.h"
#import "OWS100RemoveTSRecipientsMigration.h"
#import "OWS101ExistingUsersBlockOnIdentityChange.h"
//#import "OWS101ExistingUsersBlockOnIdentityChange.h"
#import "OWS102MoveLoggingPreferenceToUserDefaults.h"
#import "OWS103EnableVideoCalling.h"
#import "OWS104CreateRecipientIdentities.h"
NS_ASSUME_NONNULL_BEGIN
@ -28,9 +29,11 @@ NS_ASSUME_NONNULL_BEGIN
{
return @[
[[OWS100RemoveTSRecipientsMigration alloc] initWithStorageManager:self.storageManager],
[[OWS101ExistingUsersBlockOnIdentityChange alloc] initWithStorageManager:self.storageManager],
// Old nonblocking migration is no longer necessary.
// [[OWS101ExistingUsersBlockOnIdentityChange alloc] initWithStorageManager:self.storageManager],
[[OWS102MoveLoggingPreferenceToUserDefaults alloc] initWithStorageManager:self.storageManager],
[[OWS103EnableVideoCalling alloc] initWithStorageManager:self.storageManager]
[[OWS103EnableVideoCalling alloc] initWithStorageManager:self.storageManager],
[[OWS104CreateRecipientIdentities alloc] initWithStorageManager:self.storageManager]
];
}

View File

@ -2,6 +2,8 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <SignalServiceKit/TSPreferences.h>
NS_ASSUME_NONNULL_BEGIN
/**
@ -17,7 +19,7 @@ typedef NS_ENUM(NSUInteger, NotificationType) {
extern NSString *const PropertyListPreferencesSignalDatabaseCollection;
extern NSString *const PropertyListPreferencesKeyEnableDebugLog;
@interface PropertyListPreferences : NSObject
@interface PropertyListPreferences : NSObject <TSPreferences>
#pragma mark - Helpers
@ -82,8 +84,7 @@ extern NSString *const PropertyListPreferencesKeyEnableDebugLog;
#pragma mark - Block on Identity Change
- (BOOL)shouldBlockOnIdentityChange;
- (void)setShouldBlockOnIdentityChange:(BOOL)value;
- (void)setIsSendingIdentityApprovalRequired:(BOOL)value;
#pragma mark - Push Tokens

View File

@ -4,7 +4,6 @@
#import "PropertyListPreferences.h"
#import "TSStorageHeaders.h"
#import <SignalServiceKit/TSPrivacyPreferences.h>
NS_ASSUME_NONNULL_BEGIN
@ -27,6 +26,7 @@ NSString *const PropertyListPreferencesKeyCallKitPrivacyEnabled = @"CallKitPriva
NSString *const PropertyListPreferencesKeyCallsHideIPAddress = @"CallsHideIPAddress";
NSString *const PropertyListPreferencesKeyHasDeclinedNoContactsView = @"hasDeclinedNoContactsView";
NSString *const PropertyListPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNagVersion";
NSString *const PropertyListPreferencesKeyIsSendingIdentityApprovalRequired = @"IsSendingIdentityApprovalRequired";
@implementation PropertyListPreferences
@ -67,11 +67,6 @@ NSString *const PropertyListPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNag
inCollection:PropertyListPreferencesSignalDatabaseCollection];
}
- (TSPrivacyPreferences *)tsPrivacyPreferences
{
return [TSPrivacyPreferences sharedInstance];
}
#pragma mark - Specific Preferences
- (NSTimeInterval)getCachedOrDefaultDesiredBufferDepth
@ -305,15 +300,19 @@ NSString *const PropertyListPreferencesKeyIOSUpgradeNagVersion = @"iOSUpgradeNag
#pragma mark - Block on Identity Change
- (BOOL)shouldBlockOnIdentityChange
- (BOOL)isSendingIdentityApprovalRequired
{
return self.tsPrivacyPreferences.shouldBlockOnIdentityChange;
NSNumber *preference = [self tryGetValueForKey:PropertyListPreferencesKeyIsSendingIdentityApprovalRequired];
if (preference) {
return [preference boolValue];
} else {
return NO;
}
}
- (void)setShouldBlockOnIdentityChange:(BOOL)value
- (void)setIsSendingIdentityApprovalRequired:(BOOL)value
{
self.tsPrivacyPreferences.shouldBlockOnIdentityChange = value;
[self.tsPrivacyPreferences save];
[self setValueForKey:PropertyListPreferencesKeyIsSendingIdentityApprovalRequired toValue:@(value)];
}
#pragma mark - Push Tokens

View File

@ -102,6 +102,7 @@
return [NSString stringWithFormat:@"[%@]", self.class];
}
// TODO rename to logTag, tag is an existing UIView method.
- (NSString *)tag
{
return self.class.tag;

View File

@ -470,7 +470,7 @@
"ERROR_MESSAGE_NON_BLOCKING_IDENTITY_CHANGE" = "Safety number changed.";
/* Shown when signal users safety numbers changed, embeds the user's {{name or phone number}} */
"ERROR_MESSAGE_NON_BLOCKING_IDENTITY_CHANGE_FORMAT" = "ERROR_MESSAGE_NON_BLOCKING_IDENTITY_CHANGE_FORMAT";
"ERROR_MESSAGE_NON_BLOCKING_IDENTITY_CHANGE_FORMAT" = "Your safety number with %@ has changed.";
/* No comment provided by engineer. */
"ERROR_MESSAGE_UNKNOWN_ERROR" = "An unknown error occurred.";
@ -1139,10 +1139,10 @@
"SETTINGS_BLOCK_LIST_TITLE" = "Blocked";
/* User settings section footer, a detailed explanation */
"SETTINGS_BLOCK_ON_IDENITY_CHANGE_DETAIL" = "Requires your approval before communicating with someone who has a new safety number, commonly from a reinstall of Signal.";
"SETTINGS_BLOCK_ON_IDENITY_CHANGE_DETAIL" = "When a contact's safety number changes, it often means they simply reinstalled Signal. However, you may wish to verify their safety number before responding to ensure privacy.";
/* Table cell label */
"SETTINGS_BLOCK_ON_IDENTITY_CHANGE_TITLE" = "Require Approval on Change";
"SETTINGS_BLOCK_SENDING_ON_IDENTITY_CHANGE_TITLE" = "Responding Requires Approval";
/* Accessibility hint for the settings button */
"SETTINGS_BUTTON_ACCESSIBILITY" = "Settings";
@ -1199,7 +1199,7 @@
"SETTINGS_PRIVACY_TITLE" = "Privacy";
/* Section header */
"SETTINGS_PRIVACY_VERIFICATION_TITLE" = "Safety Numbers Approval";
"SETTINGS_PRIVACY_VERIFICATION_TITLE" = "When Safety Numbers Change";
/* No comment provided by engineer. */
"SETTINGS_SCREEN_SECURITY" = "Enable Screen Security";