This commit is contained in:
nielsandriesse 2020-07-21 09:11:26 +10:00
parent e7e6023542
commit b89fb68a56
12 changed files with 41 additions and 80 deletions

View file

@ -26,16 +26,6 @@ public class DotNetAPI : NSObject {
/// To be overridden by subclasses.
internal class var authTokenCollection: String { preconditionFailure("authTokenCollection is abstract and must be overridden.") }
private static func getAuthTokenFromDatabase(for server: String) -> String? {
var result: String? = nil
storage.dbReadConnection.read { transaction in
if transaction.hasObject(forKey: server, inCollection: authTokenCollection) {
result = transaction.object(forKey: server, inCollection: authTokenCollection) as? String
}
}
return result
}
internal static func getAuthToken(for server: String) -> Promise<String> {
if let token = getAuthTokenFromDatabase(for: server) {
return Promise.value(token)
@ -49,6 +39,16 @@ public class DotNetAPI : NSObject {
}
}
private static func getAuthTokenFromDatabase(for server: String) -> String? {
var result: String? = nil
storage.dbReadConnection.read { transaction in
if transaction.hasObject(forKey: server, inCollection: authTokenCollection) {
result = transaction.object(forKey: server, inCollection: authTokenCollection) as? String
}
}
return result
}
private static func setAuthToken(for server: String, to newValue: String, in transaction: YapDatabaseReadWriteTransaction) {
transaction.setObject(newValue, forKey: server, inCollection: authTokenCollection)
}

View file

@ -8,12 +8,14 @@ public final class FileServerAPI : DotNetAPI {
private static let attachmentType = "net.app.core.oembed"
public static let maxFileSize = 10_000_000 // 10 MB
@objc public static let server = "https://file.getsession.org"
// MARK: Storage
override internal class var authTokenCollection: String { return "LokiStorageAuthTokenCollection" }
// MARK: Device Links
/// - Note: Deprecated.
@objc(getDeviceLinksAssociatedWithHexEncodedPublicKey:)
public static func objc_getDeviceLinks(associatedWith hexEncodedPublicKey: String) -> AnyPromise {
return AnyPromise.from(getDeviceLinks(associatedWith: hexEncodedPublicKey))
@ -21,10 +23,13 @@ public final class FileServerAPI : DotNetAPI {
/// Gets the device links associated with the given hex encoded public key from the
/// server and stores and returns the valid ones.
///
/// - Note: Deprecated.
public static func getDeviceLinks(associatedWith hexEncodedPublicKey: String) -> Promise<Set<DeviceLink>> {
return getDeviceLinks(associatedWith: [ hexEncodedPublicKey ])
}
/// - Note: Deprecated.
@objc(getDeviceLinksAssociatedWithHexEncodedPublicKeys:)
public static func objc_getDeviceLinks(associatedWith hexEncodedPublicKeys: Set<String>) -> AnyPromise {
return AnyPromise.from(getDeviceLinks(associatedWith: hexEncodedPublicKeys))
@ -32,6 +37,8 @@ public final class FileServerAPI : DotNetAPI {
/// Gets the device links associated with the given hex encoded public keys from the
/// server and stores and returns the valid ones.
///
/// - Note: Deprecated.
public static func getDeviceLinks(associatedWith hexEncodedPublicKeys: Set<String>) -> Promise<Set<DeviceLink>> {
let hexEncodedPublicKeysDescription = "[ \(hexEncodedPublicKeys.joined(separator: ", ")) ]"
print("[Loki] Getting device links for: \(hexEncodedPublicKeysDescription).")
@ -87,7 +94,8 @@ public final class FileServerAPI : DotNetAPI {
}
}.handlingInvalidAuthTokenIfNeeded(for: server)
}
/// - Note: Deprecated.
public static func setDeviceLinks(_ deviceLinks: Set<DeviceLink>) -> Promise<Void> {
print("[Loki] Updating device links.")
return getAuthToken(for: server).then2 { token -> Promise<Void> in
@ -109,6 +117,8 @@ public final class FileServerAPI : DotNetAPI {
}
/// Adds the given device link to the user's device mapping on the server.
///
/// - Note: Deprecated.
public static func addDeviceLink(_ deviceLink: DeviceLink) -> Promise<Void> {
var deviceLinks: Set<DeviceLink> = []
storage.dbReadConnection.read { transaction in
@ -121,6 +131,8 @@ public final class FileServerAPI : DotNetAPI {
}
/// Removes the given device link from the user's device mapping on the server.
///
/// - Note: Deprecated.
public static func removeDeviceLink(_ deviceLink: DeviceLink) -> Promise<Void> {
var deviceLinks: Set<DeviceLink> = []
storage.dbReadConnection.read { transaction in

View file

@ -14,6 +14,7 @@ public enum OnionRequestAPI {
// MARK: Settings
/// The number of snodes (including the guard snode) in a path.
private static let pathSize: UInt = 3
public static let pathCount: UInt = 2
private static var guardSnodeCount: UInt { return pathCount } // One per path

View file

@ -15,6 +15,7 @@ public final class PublicChatAPI : DotNetAPI {
private static let maxRetryCount: UInt = 4
public static let profilePictureType = "network.loki.messenger.avatar"
@objc public static let publicChatMessageType = "network.loki.messenger.publicChat"
// MARK: Convenience

View file

@ -38,7 +38,7 @@
SSKProtoContentBuilder *contentBuilder = [super prepareCustomContentBuilder:recipient];
NSError *error;
if (self.kind == LKDeviceLinkMessageKindRequest) {
// The slave device attaches a pre key bundle with the request it sends, so that a
// The slave device attaches a pre key bundle with the request it sends so that a
// session can be established with the master device.
PreKeyBundle *preKeyBundle = [OWSPrimaryStorage.sharedManager generatePreKeyBundleForContact:recipient.recipientId];
SSKProtoPrekeyBundleMessageBuilder *preKeyBundleMessageBuilder = [SSKProtoPrekeyBundleMessage builderFromPreKeyBundle:preKeyBundle];
@ -51,7 +51,7 @@
}
} else {
// The master device attaches its display name and profile picture URL to the device link
// authorization message, so that the slave device is in sync with these things as soon
// authorization message so that the slave device is in sync with these things as soon
// as possible.
id<ProfileManagerProtocol> profileManager = SSKEnvironment.shared.profileManager;
NSString *displayName = profileManager.localProfileName;

View file

@ -2,8 +2,6 @@
NS_ASSUME_NONNULL_BEGIN
// TODO: This is just an ephemeral message with a flag set. Not sure if it needs to be its own type.
NS_SWIFT_NAME(UnlinkDeviceMessage)
@interface LKUnlinkDeviceMessage : TSOutgoingMessage

View file

@ -14,16 +14,16 @@ public class LokiSessionResetImplementation : NSObject, SessionResetProtocol {
public func validatePreKeyForFriendRequestAcceptance(for recipientID: String, whisperMessage: CipherMessage, protocolContext: Any?) throws {
guard let transaction = protocolContext as? YapDatabaseReadTransaction else {
print("[Loki] Couldn't verify friend request accepted message because an invalid transaction was provided.")
print("[Loki] Invalid transaction.")
return
}
guard let preKeyMessage = whisperMessage as? PreKeyWhisperMessage else { return }
guard let storedPreKey = storage.getPreKeyRecord(forContact: recipientID, transaction: transaction) else {
print("[Loki] Received a friend request accepted message from a public key for which no pre key bundle was created.")
print("[Loki] Missing pre key bundle.")
return
}
guard storedPreKey.id == preKeyMessage.prekeyID else {
print("[Loki] Received a `PreKeyWhisperMessage` (friend request accepted message) from an unknown source.")
print("[Loki] Received a `PreKeyWhisperMessage` from an unknown source.")
throw Error.preKeyIDsDontMatch
}
}

View file

@ -457,6 +457,7 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
}
}
} error:nil];
return processedJobs;
}

View file

@ -220,11 +220,11 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
[self decryptFallbackMessage:envelope
envelopeData:envelopeData
successBlock:^(OWSMessageDecryptResult *result) {
OWSLogDebug(@"Decrypted friend request message.");
OWSLogDebug(@"Decrypted fallback message.");
successBlock(result, transaction);
}
failureBlock:^(NSError * _Nullable error) {
OWSLogError(@"Decrypting friend request message from: %@ failed with error: %@.",
OWSLogError(@"Decrypting fallback message from: %@ failed with error: %@.",
envelopeAddress(envelope),
error);
failureBlock();
@ -328,8 +328,8 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
OWSAssertDebug(successBlock);
OWSAssertDebug(failureBlock);
NSData *encryptedData = envelope.content;
if (!encryptedData) {
NSData *ivAndCiphertext = envelope.content;
if (ivAndCiphertext == nil) {
OWSProdFail([OWSAnalyticsEvents messageManagerErrorMessageEnvelopeHasNoContent]);
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, @"Envelope has no content.");
return failureBlock(error);
@ -339,15 +339,15 @@ NSError *EnsureDecryptError(NSError *_Nullable error, NSString *fallbackErrorDes
ECKeyPair *identityKeyPair = self.identityManager.identityKeyPair;
FallBackSessionCipher *cipher = [[FallBackSessionCipher alloc] initWithRecipientPublicKey:recipientId privateKey:identityKeyPair.privateKey];
NSData *_Nullable plaintextData = [[cipher decrypt:encryptedData] removePadding];
if (!plaintextData) {
NSString *errorString = [NSString stringWithFormat:@"Failed to decrypt fallback message from: %@.", recipientId];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorString);
NSData *_Nullable plaintext = [[cipher decrypt:ivAndCiphertext] removePadding];
if (plaintext == nil) {
NSString *errorDescription = [NSString stringWithFormat:@"Failed to decrypt fallback message from: %@.", recipientId];
NSError *error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecryptMessage, errorDescription);
return failureBlock(error);
}
OWSMessageDecryptResult *result = [OWSMessageDecryptResult resultWithEnvelopeData:envelopeData
plaintextData:plaintextData
plaintextData:plaintext
source:envelope.source
sourceDevice:envelope.sourceDevice
isUDMessage:NO];

View file

@ -1284,10 +1284,8 @@ NS_ASSUME_NONNULL_BEGIN
// ========
}
// Loki: Handle profile key update if needed
[LKSessionMetaProtocol updateProfileKeyIfNeededForPublicKey:senderMasterPublicKey using:dataMessage];
// Loki: Handle display name update if needed
[LKSessionMetaProtocol updateDisplayNameIfNeededForPublicKey:senderMasterPublicKey using:dataMessage transaction:transaction];
switch (dataMessage.group.type) {

View file

@ -398,7 +398,6 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
successBlock:^(OWSMessageDecryptResult *result, YapDatabaseReadWriteTransaction *transaction) {
OWSAssertDebug(transaction);
// Loki: Don't process any messages from ourself
if ([LKSessionMetaProtocol shouldSkipMessageDecryptResult:result wrappedIn:envelope]) {
dispatch_async(self.serialQueue, ^{
completion(YES);
@ -448,6 +447,7 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
OWSSingletonAssert();
self = [super init];
if (!self) {
return self;
}

View file

@ -790,31 +790,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[sendPromise retainUntilComplete];
}
- (void)unregisteredRecipient:(SignalRecipient *)recipient
message:(TSOutgoingMessage *)message
thread:(TSThread *)thread
{
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
if (thread.isGroupThread) {
// Mark as "skipped" group members who no longer have signal accounts.
[message updateWithSkippedRecipient:recipient.recipientId transaction:transaction];
}
if (![SignalRecipient isRegisteredRecipient:recipient.recipientId transaction:transaction]) {
return;
}
[SignalRecipient markRecipientAsUnregistered:recipient.recipientId transaction:transaction];
[[TSInfoMessage userNotRegisteredMessageInThread:thread recipientId:recipient.recipientId]
saveWithTransaction:transaction];
// TODO: Should we deleteAllSessionsForContact here?
// If so, we'll need to avoid doing a prekey fetch every
// time we try to send a message to an unregistered user.
} error:nil];
}
- (nullable NSArray<NSDictionary *> *)deviceMessagesForMessageSend:(OWSMessageSend *)messageSend
error:(NSError **)errorHandle
{
@ -1243,27 +1218,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
});
};
void (^handle404)(void) = ^{
OWSLogWarn(@"Unregistered recipient: %@.", recipient.uniqueId);
dispatch_async(OWSDispatch.sendingQueue, ^{
if (![messageSend.message isKindOfClass:[OWSOutgoingSyncMessage class]]) {
TSThread *_Nullable thread = messageSend.thread;
OWSAssertDebug(thread);
[self unregisteredRecipient:recipient message:message thread:thread];
}
NSError *error = OWSErrorMakeNoSuchSignalRecipientError();
// No need to retry if the recipient is not registered.
[error setIsRetryable:NO];
// If one member of a group deletes their account,
// the group should ignore errors when trying to send
// messages to this ex-member.
[error setShouldBeIgnoredForGroups:YES];
messageSend.failure(error);
});
};
switch (statusCode) {
case 0: { // Loki
NSError *error;
@ -1285,10 +1239,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[error setIsRetryable:NO];
return messageSend.failure(error);
}
case 404: {
handle404();
return;
}
default:
retrySend();
break;