]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/manager/Manager.java
Use StandardCharsets.UTF_8
[signal-cli] / src / main / java / org / asamk / signal / manager / Manager.java
index 2ce59cdc0fd71dc361f39ff2e3a3964b8b20dbe0..a4127b75c369d6ce0f0c1b0ba27097f9908001ac 100644 (file)
@@ -124,6 +124,7 @@ import java.io.OutputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
@@ -267,6 +268,21 @@ public class Manager implements Closeable {
             account.setProfileKey(KeyUtils.createProfileKey());
             account.save();
         }
+        // Store profile keys only in profile store
+        for (ContactInfo contact : account.getContactStore().getContacts()) {
+            String profileKeyString = contact.profileKey;
+            if (profileKeyString == null) {
+                continue;
+            }
+            final ProfileKey profileKey;
+            try {
+                profileKey = new ProfileKey(Base64.decode(profileKeyString));
+            } catch (InvalidInputException | IOException e) {
+                continue;
+            }
+            contact.profileKey = null;
+            account.getProfileStore().storeProfileKey(contact.getAddress(), profileKey);
+        }
     }
 
     public void checkAccountState() throws IOException {
@@ -431,10 +447,9 @@ public class Manager implements Closeable {
     private SignalServiceMessageSender getMessageSender() {
         // TODO implement ZkGroup support
         final ClientZkProfileOperations clientZkProfileOperations = null;
-        final boolean attachmentsV3 = false;
         final ExecutorService executor = null;
         return new SignalServiceMessageSender(serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(),
-                account.getDeviceId(), account.getSignalProtocolStore(), userAgent, account.isMultiDevice(), attachmentsV3, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent(), clientZkProfileOperations, executor);
+                account.getDeviceId(), account.getSignalProtocolStore(), userAgent, account.isMultiDevice(), Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent(), clientZkProfileOperations, executor, ServiceConfig.MAX_ENVELOPE_SIZE);
     }
 
     private SignalServiceProfile getEncryptedRecipientProfile(SignalServiceAddress address, Optional<UnidentifiedAccess> unidentifiedAccess) throws IOException {
@@ -843,7 +858,7 @@ public class Manager implements Closeable {
         String packId = messageSender.uploadStickerManifest(manifest, packKey);
 
         try {
-            return new URI("https", "signal.art", "/addstickers/", "pack_id=" + URLEncoder.encode(packId, "utf-8") + "&pack_key=" + URLEncoder.encode(Hex.toStringCondensed(packKey), "utf-8"))
+            return new URI("https", "signal.art", "/addstickers/", "pack_id=" + URLEncoder.encode(packId, StandardCharsets.UTF_8) + "&pack_key=" + URLEncoder.encode(Hex.toStringCondensed(packKey), StandardCharsets.UTF_8))
                     .toString();
         } catch (URISyntaxException e) {
             throw new AssertionError(e);
@@ -994,16 +1009,10 @@ public class Manager implements Closeable {
     }
 
     private byte[] getTargetUnidentifiedAccessKey(SignalServiceAddress recipient) {
-        ContactInfo contact = account.getContactStore().getContact(recipient);
-        if (contact == null || contact.profileKey == null) {
+        ProfileKey theirProfileKey = account.getProfileStore().getProfileKey(recipient);
+        if (theirProfileKey == null) {
             return null;
         }
-        ProfileKey theirProfileKey;
-        try {
-            theirProfileKey = new ProfileKey(Base64.decode(contact.profileKey));
-        } catch (InvalidInputException | IOException e) {
-            throw new AssertionError(e);
-        }
         SignalProfile targetProfile;
         try {
             targetProfile = getRecipientProfile(recipient, Optional.absent(), theirProfileKey);
@@ -1198,8 +1207,9 @@ public class Manager implements Closeable {
         SignalServiceSyncMessage syncMessage = SignalServiceSyncMessage.forSentTranscript(transcript);
 
         try {
+            long startTime = System.currentTimeMillis();
             messageSender.sendMessage(syncMessage, unidentifiedAccess);
-            return SendMessageResult.success(recipient, unidentifiedAccess.isPresent(), false);
+            return SendMessageResult.success(recipient, unidentifiedAccess.isPresent(), false, System.currentTimeMillis() - startTime);
         } catch (UntrustedIdentityException e) {
             account.getSignalProtocolStore().saveIdentity(resolveSignalServiceAddress(e.getIdentifier()), e.getIdentityKey(), TrustLevel.UNTRUSTED);
             return SendMessageResult.identityFailure(recipient, e.getIdentityKey());
@@ -1326,24 +1336,16 @@ public class Manager implements Closeable {
             }
         }
         if (message.getProfileKey().isPresent() && message.getProfileKey().get().length == 32) {
+            final ProfileKey profileKey;
+            try {
+                profileKey = new ProfileKey(message.getProfileKey().get());
+            } catch (InvalidInputException e) {
+                throw new AssertionError(e);
+            }
             if (source.matches(account.getSelfAddress())) {
-                try {
-                    this.account.setProfileKey(new ProfileKey(message.getProfileKey().get()));
-                } catch (InvalidInputException ignored) {
-                }
-                ContactInfo contact = account.getContactStore().getContact(source);
-                if (contact != null) {
-                    contact.profileKey = Base64.encodeBytes(message.getProfileKey().get());
-                    account.getContactStore().updateContact(contact);
-                }
-            } else {
-                ContactInfo contact = account.getContactStore().getContact(source);
-                if (contact == null) {
-                    contact = new ContactInfo(source);
-                }
-                contact.profileKey = Base64.encodeBytes(message.getProfileKey().get());
-                account.getContactStore().updateContact(contact);
+                this.account.setProfileKey(profileKey);
             }
+            this.account.getProfileStore().storeProfileKey(source, profileKey);
         }
         if (message.getPreviews().isPresent()) {
             final List<SignalServiceDataMessage.Preview> previews = message.getPreviews().get();
@@ -1398,7 +1400,15 @@ public class Manager implements Closeable {
         if (!envelope.isReceipt()) {
             try {
                 content = decryptMessage(envelope);
-            } catch (Exception e) {
+            } catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
+                return;
+            } catch (Exception er) {
+                // All other errors are not recoverable, so delete the cached message
+                try {
+                    Files.delete(fileEntry.toPath());
+                } catch (IOException e) {
+                    System.err.println("Failed to delete cached message file “" + fileEntry + "”: " + e.getMessage());
+                }
                 return;
             }
             List<HandleAction> actions = handleMessage(envelope, content, ignoreAttachments);
@@ -1461,6 +1471,7 @@ public class Manager implements Closeable {
                                 e.printStackTrace();
                             }
                         }
+                        account.save();
                         queuedActions.clear();
                         queuedActions = null;
                     }
@@ -1476,6 +1487,7 @@ public class Manager implements Closeable {
                 System.err.println("Ignoring error: " + e.getMessage());
                 continue;
             }
+
             if (envelope.hasSource()) {
                 // Store uuid if we don't have it already
                 SignalServiceAddress source = envelope.getSourceAddress();
@@ -1510,7 +1522,8 @@ public class Manager implements Closeable {
             if (!(exception instanceof org.whispersystems.libsignal.UntrustedIdentityException)) {
                 File cacheFile = null;
                 try {
-                    cacheFile = getMessageCacheFile(envelope.getSourceE164().get(), now, envelope.getTimestamp());
+                    String source = envelope.getSourceE164().isPresent() ? envelope.getSourceE164().get() : "";
+                    cacheFile = getMessageCacheFile(source, now, envelope.getTimestamp());
                     Files.delete(cacheFile.toPath());
                     // Try to delete directory if empty
                     new File(getMessageCachePath()).delete();
@@ -1679,7 +1692,7 @@ public class Manager implements Closeable {
                                     contact.color = c.getColor().get();
                                 }
                                 if (c.getProfileKey().isPresent()) {
-                                    contact.profileKey = Base64.encodeBytes(c.getProfileKey().get().serialize());
+                                    account.getProfileStore().storeProfileKey(address, c.getProfileKey().get());
                                 }
                                 if (c.getVerified().isPresent()) {
                                     final VerifiedMessage verifiedMessage = c.getVerified().get();
@@ -1863,11 +1876,7 @@ public class Manager implements Closeable {
                         verifiedMessage = new VerifiedMessage(record.getAddress(), currentIdentity.getIdentityKey(), currentIdentity.getTrustLevel().toVerifiedState(), currentIdentity.getDateAdded().getTime());
                     }
 
-                    ProfileKey profileKey = null;
-                    try {
-                        profileKey = record.profileKey == null ? null : new ProfileKey(Base64.decode(record.profileKey));
-                    } catch (InvalidInputException ignored) {
-                    }
+                    ProfileKey profileKey = account.getProfileStore().getProfileKey(record.getAddress());
                     out.write(new DeviceContact(record.getAddress(), Optional.fromNullable(record.name),
                             createContactAvatarAttachment(record.number), Optional.fromNullable(record.color),
                             Optional.fromNullable(verifiedMessage), Optional.fromNullable(profileKey), record.blocked,