2017-09-14 17:00:30 +02:00
|
|
|
//
|
2018-06-12 17:21:49 +02:00
|
|
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
2017-09-14 17:00:30 +02:00
|
|
|
//
|
|
|
|
|
|
|
|
#import "OWSMessageHandler.h"
|
2018-06-07 07:57:59 +02:00
|
|
|
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
2017-09-14 17:00:30 +02:00
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
|
|
|
// used in log formatting
|
2018-08-01 16:45:21 +02:00
|
|
|
NSString *envelopeAddress(SSKProtoEnvelope *envelope)
|
2017-09-14 17:00:30 +02:00
|
|
|
{
|
|
|
|
return [NSString stringWithFormat:@"%@.%d", envelope.source, (unsigned int)envelope.sourceDevice];
|
|
|
|
}
|
|
|
|
|
|
|
|
@implementation OWSMessageHandler
|
|
|
|
|
2018-08-01 16:45:21 +02:00
|
|
|
- (NSString *)descriptionForEnvelopeType:(SSKProtoEnvelope *)envelope
|
2017-09-14 17:00:30 +02:00
|
|
|
{
|
2018-09-06 19:01:24 +02:00
|
|
|
OWSAssertDebug(envelope != nil);
|
2017-09-14 17:00:30 +02:00
|
|
|
|
|
|
|
switch (envelope.type) {
|
2018-08-01 16:45:21 +02:00
|
|
|
case SSKProtoEnvelopeTypeReceipt:
|
2017-09-14 17:00:30 +02:00
|
|
|
return @"DeliveryReceipt";
|
2018-08-01 16:45:21 +02:00
|
|
|
case SSKProtoEnvelopeTypeUnknown:
|
2017-09-14 17:00:30 +02:00
|
|
|
// Shouldn't happen
|
|
|
|
OWSProdFail([OWSAnalyticsEvents messageManagerErrorEnvelopeTypeUnknown]);
|
|
|
|
return @"Unknown";
|
2018-08-01 16:45:21 +02:00
|
|
|
case SSKProtoEnvelopeTypeCiphertext:
|
2017-09-14 17:00:30 +02:00
|
|
|
return @"SignalEncryptedMessage";
|
2018-08-01 16:45:21 +02:00
|
|
|
case SSKProtoEnvelopeTypeKeyExchange:
|
2017-09-14 17:00:30 +02:00
|
|
|
// Unsupported
|
|
|
|
OWSProdFail([OWSAnalyticsEvents messageManagerErrorEnvelopeTypeKeyExchange]);
|
|
|
|
return @"KeyExchange";
|
2018-08-01 16:45:21 +02:00
|
|
|
case SSKProtoEnvelopeTypePrekeyBundle:
|
2017-09-14 17:00:30 +02:00
|
|
|
return @"PreKeyEncryptedMessage";
|
2018-10-04 17:33:58 +02:00
|
|
|
case SSKProtoEnvelopeTypeUnidentifiedSender:
|
|
|
|
return @"UnidentifiedSender";
|
2019-05-08 06:23:54 +02:00
|
|
|
case SSKProtoEnvelopeTypeFriendRequest:
|
2019-05-08 05:33:47 +02:00
|
|
|
return @"LokiFriendRequest";
|
2017-09-14 17:00:30 +02:00
|
|
|
default:
|
|
|
|
// Shouldn't happen
|
|
|
|
OWSProdFail([OWSAnalyticsEvents messageManagerErrorEnvelopeTypeOther]);
|
|
|
|
return @"Other";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-01 16:45:21 +02:00
|
|
|
- (NSString *)descriptionForEnvelope:(SSKProtoEnvelope *)envelope
|
2017-09-14 17:00:30 +02:00
|
|
|
{
|
2018-09-06 19:01:24 +02:00
|
|
|
OWSAssertDebug(envelope != nil);
|
2017-09-14 17:00:30 +02:00
|
|
|
|
|
|
|
return [NSString stringWithFormat:@"<Envelope type: %@, source: %@, timestamp: %llu content.length: %lu />",
|
|
|
|
[self descriptionForEnvelopeType:envelope],
|
|
|
|
envelopeAddress(envelope),
|
|
|
|
envelope.timestamp,
|
|
|
|
(unsigned long)envelope.content.length];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* We don't want to just log `content.description` because we'd potentially log message bodies for dataMesssages and
|
|
|
|
* sync transcripts
|
|
|
|
*/
|
2018-08-01 23:13:01 +02:00
|
|
|
- (NSString *)descriptionForContent:(SSKProtoContent *)content
|
2017-09-14 17:00:30 +02:00
|
|
|
{
|
2018-08-08 19:41:12 +02:00
|
|
|
if (content.syncMessage) {
|
2017-09-14 17:00:30 +02:00
|
|
|
return [NSString stringWithFormat:@"<SyncMessage: %@ />", [self descriptionForSyncMessage:content.syncMessage]];
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (content.dataMessage) {
|
2017-09-14 17:00:30 +02:00
|
|
|
return [NSString stringWithFormat:@"<DataMessage: %@ />", [self descriptionForDataMessage:content.dataMessage]];
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (content.callMessage) {
|
2018-06-12 17:21:49 +02:00
|
|
|
NSString *callMessageDescription = [self descriptionForCallMessage:content.callMessage];
|
|
|
|
return [NSString stringWithFormat:@"<CallMessage %@ />", callMessageDescription];
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (content.nullMessage) {
|
2017-09-14 17:00:30 +02:00
|
|
|
return [NSString stringWithFormat:@"<NullMessage: %@ />", content.nullMessage];
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (content.receiptMessage) {
|
2017-09-15 21:28:44 +02:00
|
|
|
return [NSString stringWithFormat:@"<ReceiptMessage: %@ />", content.receiptMessage];
|
2018-10-31 23:14:27 +01:00
|
|
|
} else if (content.typingMessage) {
|
|
|
|
return [NSString stringWithFormat:@"<TypingMessage: %@ />", content.typingMessage];
|
2017-09-14 17:00:30 +02:00
|
|
|
} else {
|
|
|
|
// Don't fire an analytics event; if we ever add a new content type, we'd generate a ton of
|
|
|
|
// analytics traffic.
|
2019-05-27 04:57:21 +02:00
|
|
|
// Loki: Original code
|
|
|
|
// ========
|
2019-05-27 03:26:28 +02:00
|
|
|
// OWSFailDebug(@"Unknown content type.");
|
2019-05-27 04:57:21 +02:00
|
|
|
// ========
|
2017-09-14 17:00:30 +02:00
|
|
|
return @"UnknownContent";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-01 23:13:01 +02:00
|
|
|
- (NSString *)descriptionForCallMessage:(SSKProtoCallMessage *)callMessage
|
2018-06-12 17:21:49 +02:00
|
|
|
{
|
|
|
|
NSString *messageType;
|
|
|
|
UInt64 callId;
|
2018-08-08 19:41:12 +02:00
|
|
|
|
|
|
|
if (callMessage.offer) {
|
2018-06-12 17:21:49 +02:00
|
|
|
messageType = @"Offer";
|
|
|
|
callId = callMessage.offer.id;
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (callMessage.busy) {
|
2018-06-12 17:21:49 +02:00
|
|
|
messageType = @"Busy";
|
|
|
|
callId = callMessage.busy.id;
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (callMessage.answer) {
|
2018-06-12 17:21:49 +02:00
|
|
|
messageType = @"Answer";
|
|
|
|
callId = callMessage.answer.id;
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (callMessage.hangup) {
|
2018-06-12 17:21:49 +02:00
|
|
|
messageType = @"Hangup";
|
|
|
|
callId = callMessage.hangup.id;
|
|
|
|
} else if (callMessage.iceUpdate.count > 0) {
|
|
|
|
messageType = [NSString stringWithFormat:@"Ice Updates (%lu)", (unsigned long)callMessage.iceUpdate.count];
|
|
|
|
callId = callMessage.iceUpdate.firstObject.id;
|
|
|
|
} else {
|
2018-08-27 18:51:32 +02:00
|
|
|
OWSFailDebug(@"failure: unexpected call message type: %@", callMessage);
|
2018-06-12 17:21:49 +02:00
|
|
|
messageType = @"Unknown";
|
|
|
|
callId = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [NSString stringWithFormat:@"type: %@, id: %llu", messageType, callId];
|
|
|
|
}
|
|
|
|
|
2017-09-14 17:00:30 +02:00
|
|
|
/**
|
|
|
|
* We don't want to just log `dataMessage.description` because we'd potentially log message contents
|
|
|
|
*/
|
2018-08-01 23:13:01 +02:00
|
|
|
- (NSString *)descriptionForDataMessage:(SSKProtoDataMessage *)dataMessage
|
2017-09-14 17:00:30 +02:00
|
|
|
{
|
|
|
|
NSMutableString *description = [NSMutableString new];
|
|
|
|
|
2018-08-08 19:41:12 +02:00
|
|
|
if (dataMessage.group) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"(Group:YES) "];
|
|
|
|
}
|
|
|
|
|
2018-08-01 23:13:01 +02:00
|
|
|
if ((dataMessage.flags & SSKProtoDataMessageFlagsEndSession) != 0) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"EndSession"];
|
2018-08-01 23:13:01 +02:00
|
|
|
} else if ((dataMessage.flags & SSKProtoDataMessageFlagsExpirationTimerUpdate) != 0) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"ExpirationTimerUpdate"];
|
2018-08-01 23:13:01 +02:00
|
|
|
} else if ((dataMessage.flags & SSKProtoDataMessageFlagsProfileKeyUpdate) != 0) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"ProfileKey"];
|
|
|
|
} else if (dataMessage.attachments.count > 0) {
|
|
|
|
[description appendString:@"MessageWithAttachment"];
|
|
|
|
} else {
|
|
|
|
[description appendString:@"Plain"];
|
|
|
|
}
|
|
|
|
|
|
|
|
return [NSString stringWithFormat:@"<%@ />", description];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* We don't want to just log `syncMessage.description` because we'd potentially log message contents in sent transcripts
|
|
|
|
*/
|
2018-08-01 23:13:01 +02:00
|
|
|
- (NSString *)descriptionForSyncMessage:(SSKProtoSyncMessage *)syncMessage
|
2017-09-14 17:00:30 +02:00
|
|
|
{
|
|
|
|
NSMutableString *description = [NSMutableString new];
|
2018-08-08 19:41:12 +02:00
|
|
|
if (syncMessage.sent) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"SentTranscript"];
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (syncMessage.request) {
|
2018-08-01 23:13:01 +02:00
|
|
|
if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeContacts) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"ContactRequest"];
|
2018-08-01 23:13:01 +02:00
|
|
|
} else if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeGroups) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"GroupRequest"];
|
2018-08-01 23:13:01 +02:00
|
|
|
} else if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeBlocked) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"BlockedRequest"];
|
2018-08-01 23:13:01 +02:00
|
|
|
} else if (syncMessage.request.type == SSKProtoSyncMessageRequestTypeConfiguration) {
|
2017-10-03 17:11:15 +02:00
|
|
|
[description appendString:@"ConfigurationRequest"];
|
2017-09-14 17:00:30 +02:00
|
|
|
} else {
|
2018-08-27 16:29:51 +02:00
|
|
|
OWSFailDebug(@"Unknown sync message request type");
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"UnknownRequest"];
|
|
|
|
}
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (syncMessage.blocked) {
|
2017-09-14 17:00:30 +02:00
|
|
|
[description appendString:@"Blocked"];
|
|
|
|
} else if (syncMessage.read.count > 0) {
|
|
|
|
[description appendString:@"ReadReceipt"];
|
2018-08-08 19:41:12 +02:00
|
|
|
} else if (syncMessage.verified) {
|
2017-09-14 17:00:30 +02:00
|
|
|
NSString *verifiedString =
|
|
|
|
[NSString stringWithFormat:@"Verification for: %@", syncMessage.verified.destination];
|
|
|
|
[description appendString:verifiedString];
|
2019-11-12 02:11:29 +01:00
|
|
|
} else if (syncMessage.contacts) {
|
|
|
|
[description appendString:@"Contacts"];
|
2017-09-14 17:00:30 +02:00
|
|
|
} else {
|
|
|
|
[description appendString:@"Unknown"];
|
|
|
|
}
|
|
|
|
|
|
|
|
return description;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
NS_ASSUME_NONNULL_END
|