Show toast to internal users for invalid messages.
This commit is contained in:
parent
ace47c61b1
commit
78b530f8b8
3 changed files with 69 additions and 8 deletions
|
@ -133,6 +133,11 @@ object MessageDecryptor {
|
||||||
|
|
||||||
if (validationResult is EnvelopeContentValidator.Result.Invalid) {
|
if (validationResult is EnvelopeContentValidator.Result.Invalid) {
|
||||||
Log.w(TAG, "${logPrefix(envelope, cipherResult)} Invalid content! ${validationResult.reason}", validationResult.throwable)
|
Log.w(TAG, "${logPrefix(envelope, cipherResult)} Invalid content! ${validationResult.reason}", validationResult.throwable)
|
||||||
|
|
||||||
|
if (FeatureFlags.internalUser()) {
|
||||||
|
postInvalidMessageNotification(context, validationResult.reason)
|
||||||
|
}
|
||||||
|
|
||||||
return Result.Ignore(envelope, serverDeliveredTimestamp, followUpOperations.toUnmodifiableList())
|
return Result.Ignore(envelope, serverDeliveredTimestamp, followUpOperations.toUnmodifiableList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +187,7 @@ object MessageDecryptor {
|
||||||
Log.w(TAG, "${logPrefix(envelope, e)} Decryption error!", e, true)
|
Log.w(TAG, "${logPrefix(envelope, e)} Decryption error!", e, true)
|
||||||
|
|
||||||
if (FeatureFlags.internalUser()) {
|
if (FeatureFlags.internalUser()) {
|
||||||
postErrorNotification(context)
|
postDecryptionErrorNotification(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FeatureFlags.retryReceipts()) {
|
if (FeatureFlags.retryReceipts()) {
|
||||||
|
@ -324,11 +329,22 @@ object MessageDecryptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postErrorNotification(context: Context) {
|
private fun postDecryptionErrorNotification(context: Context) {
|
||||||
val notification: Notification = NotificationCompat.Builder(context, NotificationChannels.getInstance().FAILURES)
|
val notification: Notification = NotificationCompat.Builder(context, NotificationChannels.getInstance().FAILURES)
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
.setContentTitle(context.getString(R.string.MessageDecryptionUtil_failed_to_decrypt_message))
|
.setContentTitle("[Internal-only] Failed to decrypt a message!")
|
||||||
.setContentText(context.getString(R.string.MessageDecryptionUtil_tap_to_send_a_debug_log))
|
.setContentText("Tap to send a debug log")
|
||||||
|
.setContentIntent(PendingIntent.getActivity(context, 0, Intent(context, SubmitDebugLogActivity::class.java), PendingIntentFlags.mutable()))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
NotificationManagerCompat.from(context).notify(NotificationIds.INTERNAL_ERROR, notification)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun postInvalidMessageNotification(context: Context, message: String) {
|
||||||
|
val notification: Notification = NotificationCompat.Builder(context, NotificationChannels.getInstance().FAILURES)
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setContentTitle("[Internal-only] Received an invalid message!")
|
||||||
|
.setContentText("$message Tap to send a debug log.")
|
||||||
.setContentIntent(PendingIntent.getActivity(context, 0, Intent(context, SubmitDebugLogActivity::class.java), PendingIntentFlags.mutable()))
|
.setContentIntent(PendingIntent.getActivity(context, 0, Intent(context, SubmitDebugLogActivity::class.java), PendingIntentFlags.mutable()))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|
|
@ -1223,10 +1223,6 @@
|
||||||
<string name="MediaRepository_all_media">All media</string>
|
<string name="MediaRepository_all_media">All media</string>
|
||||||
<string name="MediaRepository__camera">Camera</string>
|
<string name="MediaRepository__camera">Camera</string>
|
||||||
|
|
||||||
<!-- MessageDecryptionUtil -->
|
|
||||||
<string name="MessageDecryptionUtil_failed_to_decrypt_message">Failed to decrypt message</string>
|
|
||||||
<string name="MessageDecryptionUtil_tap_to_send_a_debug_log">Tap to send a debug log</string>
|
|
||||||
|
|
||||||
<!-- MessageRecord -->
|
<!-- MessageRecord -->
|
||||||
<string name="MessageRecord_unknown">Unknown</string>
|
<string name="MessageRecord_unknown">Unknown</string>
|
||||||
<string name="MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported">Received a message encrypted using an old version of Signal that is no longer supported. Please ask the sender to update to the most recent version and resend the message.</string>
|
<string name="MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported">Received a message encrypted using an old version of Signal that is no longer supported. Please ask the sender to update to the most recent version and resend the message.</string>
|
||||||
|
|
|
@ -26,6 +26,14 @@ import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Typing
|
||||||
object EnvelopeContentValidator {
|
object EnvelopeContentValidator {
|
||||||
|
|
||||||
fun validate(envelope: Envelope, content: Content): Result {
|
fun validate(envelope: Envelope, content: Content): Result {
|
||||||
|
if (envelope.type == Envelope.Type.PLAINTEXT_CONTENT) {
|
||||||
|
val result: Result? = createPlaintextResultIfInvalid(content)
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
envelope.story && !content.meetsStoryFlagCriteria() -> Result.Invalid("Envelope was flagged as a story, but it did not have any story-related content!")
|
envelope.story && !content.meetsStoryFlagCriteria() -> Result.Invalid("Envelope was flagged as a story, but it did not have any story-related content!")
|
||||||
content.hasDataMessage() -> validateDataMessage(envelope, content.dataMessage)
|
content.hasDataMessage() -> validateDataMessage(envelope, content.dataMessage)
|
||||||
|
@ -288,6 +296,47 @@ object EnvelopeContentValidator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createPlaintextResultIfInvalid(content: Content): Result? {
|
||||||
|
val errors: MutableList<String> = mutableListOf()
|
||||||
|
|
||||||
|
if (!content.hasDecryptionErrorMessage()) {
|
||||||
|
errors += "Missing DecryptionErrorMessage"
|
||||||
|
}
|
||||||
|
if (content.hasStoryMessage()) {
|
||||||
|
errors += "Unexpected StoryMessage"
|
||||||
|
}
|
||||||
|
if (content.hasSenderKeyDistributionMessage()) {
|
||||||
|
errors += "Unexpected SenderKeyDistributionMessage"
|
||||||
|
}
|
||||||
|
if (content.hasCallMessage()) {
|
||||||
|
errors += "Unexpected CallMessage"
|
||||||
|
}
|
||||||
|
if (content.hasEditMessage()) {
|
||||||
|
errors += "Unexpected EditMessage"
|
||||||
|
}
|
||||||
|
if (content.hasNullMessage()) {
|
||||||
|
errors += "Unexpected NullMessage"
|
||||||
|
}
|
||||||
|
if (content.hasPniSignatureMessage()) {
|
||||||
|
errors += "Unexpected PniSignatureMessage"
|
||||||
|
}
|
||||||
|
if (content.hasReceiptMessage()) {
|
||||||
|
errors += "Unexpected ReceiptMessage"
|
||||||
|
}
|
||||||
|
if (content.hasSyncMessage()) {
|
||||||
|
errors += "Unexpected SyncMessage"
|
||||||
|
}
|
||||||
|
if (content.hasTypingMessage()) {
|
||||||
|
errors += "Unexpected TypingMessage"
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (errors.isNotEmpty()) {
|
||||||
|
Result.Invalid("Invalid PLAINTEXT_CONTENT! Errors: $errors")
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun validateGroupContextV2(groupContext: GroupContextV2, prefix: String): Result.Invalid? {
|
private fun validateGroupContextV2(groupContext: GroupContextV2, prefix: String): Result.Invalid? {
|
||||||
return if (!groupContext.hasMasterKey()) {
|
return if (!groupContext.hasMasterKey()) {
|
||||||
Result.Invalid("$prefix Missing GV2 master key!")
|
Result.Invalid("$prefix Missing GV2 master key!")
|
||||||
|
|
Loading…
Add table
Reference in a new issue