X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/900b648f09fa1a1c6e2d35df94c5a9d75286af01..5c117bd863c6b01e21b2865ebffd04c5cb23003c:/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 a4a9c37a..d626ccaf 100644 --- a/src/main/java/org/asamk/signal/Manager.java +++ b/src/main/java/org/asamk/signal/Manager.java @@ -37,10 +37,13 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceMessagePipe; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; import org.whispersystems.signalservice.api.SignalServiceMessageSender; -import org.whispersystems.signalservice.api.crypto.SignalServiceCipher; +import org.whispersystems.signalservice.api.crypto.*; +import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.*; +import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.TrustStore; +import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; import org.whispersystems.signalservice.api.push.exceptions.EncapsulatedExceptions; import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; @@ -58,7 +61,7 @@ class Manager implements Signal { public final static String PROJECT_NAME = Manager.class.getPackage().getImplementationTitle(); public final static String PROJECT_VERSION = Manager.class.getPackage().getImplementationVersion(); - private final static String USER_AGENT = PROJECT_NAME + " " + PROJECT_VERSION; + private final static String USER_AGENT = PROJECT_NAME == null ? null : PROJECT_NAME + " " + PROJECT_VERSION; private final static int PREKEY_MINIMUM_COUNT = 20; private static final int PREKEY_BATCH_SIZE = 100; @@ -143,9 +146,13 @@ class Manager implements Signal { groupStore = new JsonGroupStore(); } accountManager = new SignalServiceAccountManager(URL, TRUST_STORE, username, password, USER_AGENT); - if (accountManager.getPreKeysCount() < PREKEY_MINIMUM_COUNT) { - refreshPreKeys(); - save(); + try { + if (registered && accountManager.getPreKeysCount() < PREKEY_MINIMUM_COUNT) { + refreshPreKeys(); + save(); + } + } catch (AuthorizationFailedException e) { + System.err.println("Authorization failed, was the number registered elsewhere?"); } } @@ -293,7 +300,7 @@ class Manager implements Signal { @Override public void sendGroupMessage(String messageText, List attachments, byte[] groupId) - throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException { + throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException, UntrustedIdentityException { final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder().withBody(messageText); if (attachments != null) { messageBuilder.withAttachments(getSignalServiceAttachments(attachments)); @@ -309,7 +316,7 @@ class Manager implements Signal { sendMessage(message, groupStore.getGroup(groupId).members); } - public void sendQuitGroupMessage(byte[] groupId) throws GroupNotFoundException, IOException, EncapsulatedExceptions { + public void sendQuitGroupMessage(byte[] groupId) throws GroupNotFoundException, IOException, EncapsulatedExceptions, UntrustedIdentityException { SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.QUIT) .withId(groupId) .build(); @@ -321,7 +328,7 @@ class Manager implements Signal { sendMessage(message, groupStore.getGroup(groupId).members); } - public byte[] sendUpdateGroupMessage(byte[] groupId, String name, Collection members, String avatarFile) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException { + public byte[] sendUpdateGroupMessage(byte[] groupId, String name, Collection members, String avatarFile) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException, UntrustedIdentityException { GroupInfo g; if (groupId == null) { // Create new group @@ -374,7 +381,7 @@ class Manager implements Signal { @Override public void sendMessage(String message, List attachments, String recipient) - throws EncapsulatedExceptions, AttachmentInvalidException, IOException { + throws EncapsulatedExceptions, AttachmentInvalidException, IOException, UntrustedIdentityException { List recipients = new ArrayList<>(1); recipients.add(recipient); sendMessage(message, attachments, recipients); @@ -383,7 +390,7 @@ class Manager implements Signal { @Override public void sendMessage(String messageText, List attachments, List recipients) - throws IOException, EncapsulatedExceptions, AttachmentInvalidException { + throws IOException, EncapsulatedExceptions, AttachmentInvalidException, UntrustedIdentityException { final SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder().withBody(messageText); if (attachments != null) { messageBuilder.withAttachments(getSignalServiceAttachments(attachments)); @@ -394,7 +401,7 @@ class Manager implements Signal { } @Override - public void sendEndSessionMessage(List recipients) throws IOException, EncapsulatedExceptions { + public void sendEndSessionMessage(List recipients) throws IOException, EncapsulatedExceptions, UntrustedIdentityException { SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder() .asEndSessionMessage() .build(); @@ -403,7 +410,7 @@ class Manager implements Signal { } private void sendMessage(SignalServiceDataMessage message, Collection recipients) - throws IOException, EncapsulatedExceptions { + throws IOException, EncapsulatedExceptions, UntrustedIdentityException { SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, username, password, signalProtocolStore, USER_AGENT, Optional.absent()); @@ -419,7 +426,14 @@ class Manager implements Signal { } } - messageSender.sendMessage(new ArrayList<>(recipientsTS), message); + if (message.getGroupInfo().isPresent()) { + messageSender.sendMessage(new ArrayList<>(recipientsTS), message); + } else { + // Send to all individually, so sync messages are sent correctly + for (SignalServiceAddress address : recipientsTS) { + messageSender.sendMessage(address, message); + } + } if (message.isEndSession()) { for (SignalServiceAddress recipient : recipientsTS) { @@ -448,6 +462,73 @@ class Manager implements Signal { void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent decryptedContent, GroupInfo group); } + private GroupInfo handleSignalServiceDataMessage(SignalServiceDataMessage message, boolean isSync, String source, String destination) { + GroupInfo group = null; + if (message.getGroupInfo().isPresent()) { + SignalServiceGroup groupInfo = message.getGroupInfo().get(); + switch (groupInfo.getType()) { + case UPDATE: + try { + group = groupStore.getGroup(groupInfo.getGroupId()); + } catch (GroupNotFoundException e) { + group = new GroupInfo(groupInfo.getGroupId()); + } + + if (groupInfo.getAvatar().isPresent()) { + SignalServiceAttachment avatar = groupInfo.getAvatar().get(); + if (avatar.isPointer()) { + long avatarId = avatar.asPointer().getId(); + try { + retrieveAttachment(avatar.asPointer()); + group.avatarId = avatarId; + } catch (IOException | InvalidMessageException e) { + System.err.println("Failed to retrieve group avatar (" + avatarId + "): " + e.getMessage()); + } + } + } + + if (groupInfo.getName().isPresent()) { + group.name = groupInfo.getName().get(); + } + + if (groupInfo.getMembers().isPresent()) { + group.members.addAll(groupInfo.getMembers().get()); + } + + groupStore.updateGroup(group); + break; + case DELIVER: + try { + group = groupStore.getGroup(groupInfo.getGroupId()); + } catch (GroupNotFoundException e) { + } + break; + case QUIT: + try { + group = groupStore.getGroup(groupInfo.getGroupId()); + group.members.remove(source); + } catch (GroupNotFoundException e) { + } + break; + } + } + if (message.isEndSession()) { + handleEndSession(isSync ? destination : source); + } + if (message.getAttachments().isPresent()) { + for (SignalServiceAttachment attachment : message.getAttachments().get()) { + if (attachment.isPointer()) { + try { + retrieveAttachment(attachment.asPointer()); + } catch (IOException | InvalidMessageException e) { + System.err.println("Failed to retrieve attachment (" + attachment.asPointer().getId() + "): " + e.getMessage()); + } + } + } + } + return group; + } + public void receiveMessages(int timeoutSeconds, boolean returnOnTimeout, ReceiveMessageHandler handler) throws IOException { final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(URL, TRUST_STORE, username, password, signalingKey, USER_AGENT); SignalServiceMessagePipe messagePipe = null; @@ -466,67 +547,19 @@ class Manager implements Signal { if (content != null) { if (content.getDataMessage().isPresent()) { SignalServiceDataMessage message = content.getDataMessage().get(); - if (message.getGroupInfo().isPresent()) { - SignalServiceGroup groupInfo = message.getGroupInfo().get(); - switch (groupInfo.getType()) { - case UPDATE: - try { - group = groupStore.getGroup(groupInfo.getGroupId()); - } catch (GroupNotFoundException e) { - group = new GroupInfo(groupInfo.getGroupId()); - } - - if (groupInfo.getAvatar().isPresent()) { - SignalServiceAttachment avatar = groupInfo.getAvatar().get(); - if (avatar.isPointer()) { - long avatarId = avatar.asPointer().getId(); - try { - retrieveAttachment(avatar.asPointer()); - group.avatarId = avatarId; - } catch (IOException | InvalidMessageException e) { - System.err.println("Failed to retrieve group avatar (" + avatarId + "): " + e.getMessage()); - } - } - } - - if (groupInfo.getName().isPresent()) { - group.name = groupInfo.getName().get(); - } - - if (groupInfo.getMembers().isPresent()) { - group.members.addAll(groupInfo.getMembers().get()); - } - - groupStore.updateGroup(group); - break; - case DELIVER: - try { - group = groupStore.getGroup(groupInfo.getGroupId()); - } catch (GroupNotFoundException e) { - } - break; - case QUIT: - try { - group = groupStore.getGroup(groupInfo.getGroupId()); - group.members.remove(envelope.getSource()); - } catch (GroupNotFoundException e) { - } - break; - } + group = handleSignalServiceDataMessage(message, false, envelope.getSource(), username); + } + if (content.getSyncMessage().isPresent()) { + SignalServiceSyncMessage syncMessage = content.getSyncMessage().get(); + if (syncMessage.getSent().isPresent()) { + SignalServiceDataMessage message = syncMessage.getSent().get().getMessage(); + group = handleSignalServiceDataMessage(message, true, envelope.getSource(), syncMessage.getSent().get().getDestination().get()); } - if (message.isEndSession()) { - handleEndSession(envelope.getSource()); + if (syncMessage.getRequest().isPresent()) { + // TODO } - if (message.getAttachments().isPresent()) { - for (SignalServiceAttachment attachment : message.getAttachments().get()) { - if (attachment.isPointer()) { - try { - retrieveAttachment(attachment.asPointer()); - } catch (IOException | InvalidMessageException e) { - System.err.println("Failed to retrieve attachment (" + attachment.asPointer().getId() + "): " + e.getMessage()); - } - } - } + if (syncMessage.getGroups().isPresent()) { + // TODO } } }