X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/4377a2179b38360b00efc1c1db00a62f3f020db1..9b56aa625959f3bc8d0fa6bedc4be52b4862b053:/src/main/java/org/asamk/signal/Manager.java diff --git a/src/main/java/org/asamk/signal/Manager.java b/src/main/java/org/asamk/signal/Manager.java index c9252f83..f159e412 100644 --- a/src/main/java/org/asamk/signal/Manager.java +++ b/src/main/java/org/asamk/signal/Manager.java @@ -35,7 +35,6 @@ import org.asamk.signal.storage.protocol.JsonIdentityKeyStore; import org.asamk.signal.storage.protocol.JsonSignalProtocolStore; import org.asamk.signal.storage.threads.JsonThreadStore; import org.asamk.signal.storage.threads.ThreadInfo; -import org.asamk.signal.util.Base64; import org.asamk.signal.util.Util; import org.whispersystems.libsignal.*; import org.whispersystems.libsignal.ecc.Curve; @@ -64,6 +63,7 @@ import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.SignalServiceUrl; +import org.whispersystems.signalservice.internal.util.Base64; import java.io.*; import java.net.URI; @@ -368,7 +368,7 @@ class Manager implements Signal { } public void updateAccountAttributes() throws IOException { - accountManager.setAccountAttributes(signalingKey, signalProtocolStore.getLocalRegistrationId(), false, false, true); + accountManager.setAccountAttributes(signalingKey, signalProtocolStore.getLocalRegistrationId(), true); } public void unregister() throws IOException { @@ -481,24 +481,6 @@ class Manager implements Signal { return records; } - private PreKeyRecord getOrGenerateLastResortPreKey() { - if (signalProtocolStore.containsPreKey(Medium.MAX_VALUE)) { - try { - return signalProtocolStore.loadPreKey(Medium.MAX_VALUE); - } catch (InvalidKeyIdException e) { - signalProtocolStore.removePreKey(Medium.MAX_VALUE); - } - } - - ECKeyPair keyPair = Curve.generateKeyPair(); - PreKeyRecord record = new PreKeyRecord(Medium.MAX_VALUE, keyPair); - - signalProtocolStore.storePreKey(Medium.MAX_VALUE, record); - save(); - - return record; - } - private SignedPreKeyRecord generateSignedPreKey(IdentityKeyPair identityKeyPair) { try { ECKeyPair keyPair = Curve.generateKeyPair(); @@ -518,7 +500,7 @@ class Manager implements Signal { public void verifyAccount(String verificationCode) throws IOException { verificationCode = verificationCode.replace("-", ""); signalingKey = Util.getSecret(52); - accountManager.verifyAccountWithCode(verificationCode, signalingKey, signalProtocolStore.getLocalRegistrationId(), false, false, true); + accountManager.verifyAccountWithCode(verificationCode, signalingKey, signalProtocolStore.getLocalRegistrationId(), true); //accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID))); registered = true; @@ -529,10 +511,9 @@ class Manager implements Signal { private void refreshPreKeys() throws IOException { List oneTimePreKeys = generatePreKeys(); - PreKeyRecord lastResortKey = getOrGenerateLastResortPreKey(); SignedPreKeyRecord signedPreKeyRecord = generateSignedPreKey(signalProtocolStore.getIdentityKeyPair()); - accountManager.setPreKeys(signalProtocolStore.getIdentityKeyPair().getPublicKey(), lastResortKey, signedPreKeyRecord, oneTimePreKeys); + accountManager.setPreKeys(signalProtocolStore.getIdentityKeyPair().getPublicKey(), signedPreKeyRecord, oneTimePreKeys); } @@ -807,9 +788,9 @@ class Manager implements Signal { if (contact == null) { contact = new ContactInfo(); contact.number = number; - System.out.println("Add contact " + number + " named " + name); + System.err.println("Add contact " + number + " named " + name); } else { - System.out.println("Updating contact " + number + " name " + contact.name + " -> " + name); + System.err.println("Updating contact " + number + " name " + contact.name + " -> " + name); } contact.name = name; contactStore.updateContact(contact); @@ -1113,9 +1094,11 @@ class Manager implements Signal { try { Files.delete(fileEntry.toPath()); } catch (IOException e) { - System.out.println("Failed to delete cached message file “" + fileEntry + "”: " + e.getMessage()); + System.err.println("Failed to delete cached message file “" + fileEntry + "”: " + e.getMessage()); } } + // Try to delete directory if empty + dir.delete(); } } @@ -1169,8 +1152,10 @@ class Manager implements Signal { try { cacheFile = getMessageCacheFile(envelope.getSource(), now, envelope.getTimestamp()); Files.delete(cacheFile.toPath()); + // Try to delete directory if empty + new File(getMessageCachePath()).delete(); } catch (IOException e) { - System.out.println("Failed to delete cached message file “" + cacheFile + "”: " + e.getMessage()); + System.err.println("Failed to delete cached message file “" + cacheFile + "”: " + e.getMessage()); } } } @@ -1199,7 +1184,6 @@ class Manager implements Signal { if (rm.isContactsRequest()) { try { sendContacts(); - sendVerifiedMessage(); } catch (UntrustedIdentityException | IOException e) { e.printStackTrace(); } @@ -1216,23 +1200,25 @@ class Manager implements Signal { File tmpFile = null; try { tmpFile = Util.createTempFile(); - DeviceGroupsInputStream s = new DeviceGroupsInputStream(retrieveAttachmentAsStream(syncMessage.getGroups().get().asPointer(), tmpFile)); - DeviceGroup g; - while ((g = s.read()) != null) { - GroupInfo syncGroup = groupStore.getGroup(g.getId()); - if (syncGroup == null) { - syncGroup = new GroupInfo(g.getId()); + try (InputStream attachmentAsStream = retrieveAttachmentAsStream(syncMessage.getGroups().get().asPointer(), tmpFile)) { + DeviceGroupsInputStream s = new DeviceGroupsInputStream(attachmentAsStream); + DeviceGroup g; + while ((g = s.read()) != null) { + GroupInfo syncGroup = groupStore.getGroup(g.getId()); + if (syncGroup == null) { + syncGroup = new GroupInfo(g.getId()); + } + if (g.getName().isPresent()) { + syncGroup.name = g.getName().get(); + } + syncGroup.members.addAll(g.getMembers()); + syncGroup.active = g.isActive(); + + if (g.getAvatar().isPresent()) { + retrieveGroupAvatarAttachment(g.getAvatar().get(), syncGroup.groupId); + } + groupStore.updateGroup(syncGroup); } - if (g.getName().isPresent()) { - syncGroup.name = g.getName().get(); - } - syncGroup.members.addAll(g.getMembers()); - syncGroup.active = g.isActive(); - - if (g.getAvatar().isPresent()) { - retrieveGroupAvatarAttachment(g.getAvatar().get(), syncGroup.groupId); - } - groupStore.updateGroup(syncGroup); } } catch (Exception e) { e.printStackTrace(); @@ -1241,7 +1227,7 @@ class Manager implements Signal { try { Files.delete(tmpFile.toPath()); } catch (IOException e) { - System.out.println("Failed to delete temp file “" + tmpFile + "”: " + e.getMessage()); + System.err.println("Failed to delete received groups temp file “" + tmpFile + "”: " + e.getMessage()); } } } @@ -1254,27 +1240,29 @@ class Manager implements Signal { try { tmpFile = Util.createTempFile(); final ContactsMessage contactsMessage = syncMessage.getContacts().get(); - DeviceContactsInputStream s = new DeviceContactsInputStream(retrieveAttachmentAsStream(contactsMessage.getContactsStream().asPointer(), tmpFile)); - if (contactsMessage.isComplete()) { - contactStore.clear(); - } - DeviceContact c; - while ((c = s.read()) != null) { - ContactInfo contact = contactStore.getContact(c.getNumber()); - if (contact == null) { - contact = new ContactInfo(); - contact.number = c.getNumber(); - } - if (c.getName().isPresent()) { - contact.name = c.getName().get(); + try (InputStream attachmentAsStream = retrieveAttachmentAsStream(contactsMessage.getContactsStream().asPointer(), tmpFile)) { + DeviceContactsInputStream s = new DeviceContactsInputStream(attachmentAsStream); + if (contactsMessage.isComplete()) { + contactStore.clear(); } - if (c.getColor().isPresent()) { - contact.color = c.getColor().get(); - } - contactStore.updateContact(contact); - - if (c.getAvatar().isPresent()) { - retrieveContactAvatarAttachment(c.getAvatar().get(), contact.number); + DeviceContact c; + while ((c = s.read()) != null) { + ContactInfo contact = contactStore.getContact(c.getNumber()); + if (contact == null) { + contact = new ContactInfo(); + contact.number = c.getNumber(); + } + if (c.getName().isPresent()) { + contact.name = c.getName().get(); + } + if (c.getColor().isPresent()) { + contact.color = c.getColor().get(); + } + contactStore.updateContact(contact); + + if (c.getAvatar().isPresent()) { + retrieveContactAvatarAttachment(c.getAvatar().get(), contact.number); + } } } } catch (Exception e) { @@ -1284,16 +1272,14 @@ class Manager implements Signal { try { Files.delete(tmpFile.toPath()); } catch (IOException e) { - System.out.println("Failed to delete temp file “" + tmpFile + "”: " + e.getMessage()); + System.err.println("Failed to delete received contacts temp file “" + tmpFile + "”: " + e.getMessage()); } } } } if (syncMessage.getVerified().isPresent()) { - final List verifiedList = syncMessage.getVerified().get(); - for (VerifiedMessage v : verifiedList) { - signalProtocolStore.saveIdentity(v.getDestination(), v.getIdentityKey(), TrustLevel.fromVerifiedState(v.getVerified())); - } + final VerifiedMessage verifiedMessage = syncMessage.getVerified().get(); + signalProtocolStore.saveIdentity(verifiedMessage.getDestination(), verifiedMessage.getIdentityKey(), TrustLevel.fromVerifiedState(verifiedMessage.getVerified())); } } } @@ -1439,7 +1425,7 @@ class Manager implements Signal { try { Files.delete(tmpFile.toPath()); } catch (IOException e) { - System.out.println("Failed to delete temp file “" + tmpFile + "”: " + e.getMessage()); + System.err.println("Failed to delete received attachment temp file “" + tmpFile + "”: " + e.getMessage()); } } return outputFile; @@ -1493,7 +1479,7 @@ class Manager implements Signal { try { Files.delete(groupsFile.toPath()); } catch (IOException e) { - System.out.println("Failed to delete temp file “" + groupsFile + "”: " + e.getMessage()); + System.err.println("Failed to delete groups temp file “" + groupsFile + "”: " + e.getMessage()); } } } @@ -1505,8 +1491,21 @@ class Manager implements Signal { try (OutputStream fos = new FileOutputStream(contactsFile)) { DeviceContactsOutputStream out = new DeviceContactsOutputStream(fos); for (ContactInfo record : contactStore.getContacts()) { + VerifiedMessage verifiedMessage = null; + if (getIdentities().containsKey(record.number)) { + JsonIdentityKeyStore.Identity currentIdentity = null; + for (JsonIdentityKeyStore.Identity id : getIdentities().get(record.number)) { + if (currentIdentity == null || id.getDateAdded().after(currentIdentity.getDateAdded())) { + currentIdentity = id; + } + } + if (currentIdentity != null) { + verifiedMessage = new VerifiedMessage(record.number, currentIdentity.getIdentityKey(), currentIdentity.getTrustLevel().toVerifiedState(), currentIdentity.getDateAdded().getTime()); + } + } + out.write(new DeviceContact(record.number, Optional.fromNullable(record.name), - createContactAvatarAttachment(record.number), Optional.fromNullable(record.color))); + createContactAvatarAttachment(record.number), Optional.fromNullable(record.color), Optional.fromNullable(verifiedMessage))); } } @@ -1525,28 +1524,13 @@ class Manager implements Signal { try { Files.delete(contactsFile.toPath()); } catch (IOException e) { - System.out.println("Failed to delete temp file “" + contactsFile + "”: " + e.getMessage()); - } - } - } - - private void sendVerifiedMessage() throws IOException, UntrustedIdentityException { - List verifiedMessages = new LinkedList<>(); - for (Map.Entry> x : getIdentities().entrySet()) { - final String name = x.getKey(); - for (JsonIdentityKeyStore.Identity id : x.getValue()) { - if (id.getTrustLevel() == TrustLevel.TRUSTED_UNVERIFIED) { - continue; - } - VerifiedMessage verifiedMessage = new VerifiedMessage(name, id.getIdentityKey(), id.getTrustLevel().toVerifiedState()); - verifiedMessages.add(verifiedMessage); + System.err.println("Failed to delete contacts temp file “" + contactsFile + "”: " + e.getMessage()); } } - sendSyncMessage(SignalServiceSyncMessage.forVerified(verifiedMessages)); } private void sendVerifiedMessage(String destination, IdentityKey identityKey, TrustLevel trustLevel) throws IOException, UntrustedIdentityException { - VerifiedMessage verifiedMessage = new VerifiedMessage(destination, identityKey, trustLevel.toVerifiedState()); + VerifiedMessage verifiedMessage = new VerifiedMessage(destination, identityKey, trustLevel.toVerifiedState(), System.currentTimeMillis()); sendSyncMessage(SignalServiceSyncMessage.forVerified(verifiedMessage)); }