From: AsamK Date: Sun, 18 Nov 2018 10:08:24 +0000 (+0100) Subject: Move Manager to sub package X-Git-Tag: v0.6.1~13 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/701328b8c26d6ad4f98cf8213dd57e4b06aa1281 Move Manager to sub package --- diff --git a/src/main/java/org/asamk/signal/Main.java b/src/main/java/org/asamk/signal/Main.java index 03d1c3cc..e534f05e 100644 --- a/src/main/java/org/asamk/signal/Main.java +++ b/src/main/java/org/asamk/signal/Main.java @@ -1,18 +1,18 @@ -/** - * Copyright (C) 2015 AsamK - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . +/* + Copyright (C) 2015-2018 AsamK + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ package org.asamk.signal; @@ -28,6 +28,8 @@ import net.sourceforge.argparse4j.impl.Arguments; import net.sourceforge.argparse4j.inf.*; import org.apache.http.util.TextUtils; import org.asamk.Signal; +import org.asamk.signal.manager.BaseConfig; +import org.asamk.signal.manager.Manager; import org.asamk.signal.storage.contacts.ContactInfo; import org.asamk.signal.storage.groups.GroupInfo; import org.asamk.signal.storage.protocol.JsonIdentityKeyStore; @@ -756,7 +758,7 @@ public class Main { .build() .defaultHelp(true) .description("Commandline interface for Signal.") - .version(Manager.PROJECT_NAME + " " + Manager.PROJECT_VERSION); + .version(BaseConfig.PROJECT_NAME + " " + BaseConfig.PROJECT_VERSION); parser.addArgument("-v", "--version") .help("Show package version.") diff --git a/src/main/java/org/asamk/signal/manager/BaseConfig.java b/src/main/java/org/asamk/signal/manager/BaseConfig.java new file mode 100644 index 00000000..19d43fc8 --- /dev/null +++ b/src/main/java/org/asamk/signal/manager/BaseConfig.java @@ -0,0 +1,33 @@ +package org.asamk.signal.manager; + +import org.whispersystems.signalservice.api.push.TrustStore; +import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; +import org.whispersystems.signalservice.internal.configuration.SignalContactDiscoveryUrl; +import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; +import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl; + +public class BaseConfig { + + private BaseConfig() { + } + + public final static String PROJECT_NAME = Manager.class.getPackage().getImplementationTitle(); + public final static String PROJECT_VERSION = Manager.class.getPackage().getImplementationVersion(); + final static String USER_AGENT = PROJECT_NAME == null ? null : PROJECT_NAME + " " + PROJECT_VERSION; + + private final static String URL = "https://textsecure-service.whispersystems.org"; + private final static String CDN_URL = "https://cdn.signal.org"; + + private final static TrustStore TRUST_STORE = new WhisperTrustStore(); + final static SignalServiceConfiguration serviceConfiguration = new SignalServiceConfiguration( + new SignalServiceUrl[]{new SignalServiceUrl(URL, TRUST_STORE)}, + new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)}, + new SignalContactDiscoveryUrl[0] + ); + + final static String UNIDENTIFIED_SENDER_TRUST_ROOT = "BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF"; + + final static int PREKEY_MINIMUM_COUNT = 20; + static final int PREKEY_BATCH_SIZE = 100; + static final int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024; +} diff --git a/src/main/java/org/asamk/signal/Manager.java b/src/main/java/org/asamk/signal/manager/Manager.java similarity index 92% rename from src/main/java/org/asamk/signal/Manager.java rename to src/main/java/org/asamk/signal/manager/Manager.java index dc3916de..a97c11ea 100644 --- a/src/main/java/org/asamk/signal/Manager.java +++ b/src/main/java/org/asamk/signal/manager/Manager.java @@ -1,20 +1,20 @@ -/** - * Copyright (C) 2015 AsamK - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . +/* + Copyright (C) 2015-2018 AsamK + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ -package org.asamk.signal; +package org.asamk.signal.manager; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; @@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.http.util.TextUtils; import org.asamk.Signal; +import org.asamk.signal.*; import org.asamk.signal.storage.contacts.ContactInfo; import org.asamk.signal.storage.contacts.JsonContactsStore; import org.asamk.signal.storage.groups.GroupInfo; @@ -63,7 +64,6 @@ import org.whispersystems.signalservice.api.messages.*; import org.whispersystems.signalservice.api.messages.multidevice.*; import org.whispersystems.signalservice.api.push.ContactTokenDetails; 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.push.exceptions.NetworkFailureException; @@ -72,10 +72,6 @@ import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.util.UptimeSleepTimer; -import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; -import org.whispersystems.signalservice.internal.configuration.SignalContactDiscoveryUrl; -import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; -import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.util.Base64; @@ -93,24 +89,7 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -class Manager implements Signal { - private final static String URL = "https://textsecure-service.whispersystems.org"; - private final static String CDN_URL = "https://cdn.signal.org"; - private final static TrustStore TRUST_STORE = new WhisperTrustStore(); - private final static SignalServiceConfiguration serviceConfiguration = new SignalServiceConfiguration( - new SignalServiceUrl[]{new SignalServiceUrl(URL, TRUST_STORE)}, - new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)}, - new SignalContactDiscoveryUrl[0] - ); - private final static String UNIDENTIFIED_SENDER_TRUST_ROOT = "BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF"; - - 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 == null ? null : PROJECT_NAME + " " + PROJECT_VERSION; - - private final static int PREKEY_MINIMUM_COUNT = 20; - private static final int PREKEY_BATCH_SIZE = 100; - private static final int MAX_ATTACHMENT_SIZE = 150 * 1024 * 1024; +public class Manager implements Signal { private final String settingsPath; private final String dataPath; @@ -231,9 +210,9 @@ class Manager implements Signal { migrateLegacyConfigs(); - accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, deviceId, USER_AGENT, timer); + accountManager = new SignalServiceAccountManager(BaseConfig.serviceConfiguration, username, password, deviceId, BaseConfig.USER_AGENT, timer); try { - if (registered && accountManager.getPreKeysCount() < PREKEY_MINIMUM_COUNT) { + if (registered && accountManager.getPreKeysCount() < BaseConfig.PREKEY_MINIMUM_COUNT) { refreshPreKeys(); save(); } @@ -366,7 +345,7 @@ class Manager implements Signal { public void register(boolean voiceVerification) throws IOException { password = KeyUtils.createPassword(); - accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, USER_AGENT, timer); + accountManager = new SignalServiceAccountManager(BaseConfig.serviceConfiguration, username, password, BaseConfig.USER_AGENT, timer); if (voiceVerification) accountManager.requestVoiceVerificationCode(); @@ -391,7 +370,7 @@ class Manager implements Signal { public URI getDeviceLinkUri() throws TimeoutException, IOException { password = KeyUtils.createPassword(); - accountManager = new SignalServiceAccountManager(serviceConfiguration, username, password, USER_AGENT, timer); + accountManager = new SignalServiceAccountManager(BaseConfig.serviceConfiguration, username, password, BaseConfig.USER_AGENT, timer); String uuid = accountManager.getNewDeviceUuid(); registered = false; @@ -459,7 +438,7 @@ class Manager implements Signal { private List generatePreKeys() { List records = new LinkedList<>(); - for (int i = 0; i < PREKEY_BATCH_SIZE; i++) { + for (int i = 0; i < BaseConfig.PREKEY_BATCH_SIZE; i++) { int preKeyId = (preKeyIdOffset + i) % Medium.MAX_VALUE; ECKeyPair keyPair = Curve.generateKeyPair(); PreKeyRecord record = new PreKeyRecord(preKeyId, keyPair); @@ -468,7 +447,7 @@ class Manager implements Signal { records.add(record); } - preKeyIdOffset = (preKeyIdOffset + PREKEY_BATCH_SIZE + 1) % Medium.MAX_VALUE; + preKeyIdOffset = (preKeyIdOffset + BaseConfig.PREKEY_BATCH_SIZE + 1) % Medium.MAX_VALUE; save(); return records; @@ -625,7 +604,7 @@ class Manager implements Signal { sendMessageLegacy(messageBuilder, g.members); } - public byte[] sendUpdateGroupMessage(byte[] groupId, String name, Collection members, String avatarFile) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException { + private byte[] sendUpdateGroupMessage(byte[] groupId, String name, Collection members, String avatarFile) throws IOException, EncapsulatedExceptions, GroupNotFoundException, AttachmentInvalidException { GroupInfo g; if (groupId == null) { // Create new group @@ -793,7 +772,7 @@ class Manager implements Signal { @Override public List getGroupIds() { List groups = getGroups(); - List ids = new ArrayList(groups.size()); + List ids = new ArrayList<>(groups.size()); for (GroupInfo group : groups) { ids.add(group.groupId); } @@ -814,9 +793,9 @@ class Manager implements Signal { public List getGroupMembers(byte[] groupId) { GroupInfo group = getGroup(groupId); if (group == null) { - return new ArrayList(); + return new ArrayList<>(); } else { - return new ArrayList(group.members); + return new ArrayList<>(group.members); } } @@ -837,6 +816,19 @@ class Manager implements Signal { return sendUpdateGroupMessage(groupId, name, members, avatar); } + + /** + * Change the expiration timer for a thread (number of groupId) + * + * @param numberOrGroupId + * @param messageExpirationTimer + */ + public void setExpirationTimer(String numberOrGroupId, int messageExpirationTimer) { + ThreadInfo thread = threadStore.getThread(numberOrGroupId); + thread.messageExpirationTime = messageExpirationTimer; + threadStore.updateThread(thread); + } + private void requestSyncGroups() throws IOException { SignalServiceProtos.SyncMessage.Request r = SignalServiceProtos.SyncMessage.Request.newBuilder().setType(SignalServiceProtos.SyncMessage.Request.Type.GROUPS).build(); SignalServiceSyncMessage message = SignalServiceSyncMessage.forRequest(new RequestMessage(r)); @@ -866,12 +858,12 @@ class Manager implements Signal { return null; } - public Optional getAccessForSync() { + private Optional getAccessForSync() { // TODO implement return Optional.absent(); } - public List> getAccessFor(Collection recipients) { + private List> getAccessFor(Collection recipients) { List> result = new ArrayList<>(recipients.size()); for (SignalServiceAddress recipient : recipients) { result.add(Optional.absent()); @@ -879,15 +871,15 @@ class Manager implements Signal { return result; } - public Optional getAccessFor(SignalServiceAddress recipient) { + private Optional getAccessFor(SignalServiceAddress recipient) { // TODO implement return Optional.absent(); } private void sendSyncMessage(SignalServiceSyncMessage message) throws IOException, UntrustedIdentityException { - SignalServiceMessageSender messageSender = new SignalServiceMessageSender(serviceConfiguration, username, password, - deviceId, signalProtocolStore, USER_AGENT, isMultiDevice, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent()); + SignalServiceMessageSender messageSender = new SignalServiceMessageSender(BaseConfig.serviceConfiguration, username, password, + deviceId, signalProtocolStore, BaseConfig.USER_AGENT, isMultiDevice, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent()); try { messageSender.sendMessage(message, getAccessForSync()); } catch (UntrustedIdentityException e) { @@ -928,8 +920,8 @@ class Manager implements Signal { SignalServiceDataMessage message = null; try { - SignalServiceMessageSender messageSender = new SignalServiceMessageSender(serviceConfiguration, username, password, - deviceId, signalProtocolStore, USER_AGENT, isMultiDevice, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent()); + SignalServiceMessageSender messageSender = new SignalServiceMessageSender(BaseConfig.serviceConfiguration, username, password, + deviceId, signalProtocolStore, BaseConfig.USER_AGENT, isMultiDevice, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent()); message = messageBuilder.build(); if (message.getGroupInfo().isPresent()) { @@ -991,16 +983,16 @@ class Manager implements Signal { return recipientsTS; } - public static CertificateValidator getCertificateValidator() { + private static CertificateValidator getCertificateValidator() { try { - ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.decode(UNIDENTIFIED_SENDER_TRUST_ROOT), 0); + ECPublicKey unidentifiedSenderTrustRoot = Curve.decodePoint(Base64.decode(BaseConfig.UNIDENTIFIED_SENDER_TRUST_ROOT), 0); return new CertificateValidator(unidentifiedSenderTrustRoot); } catch (InvalidKeyException | IOException e) { throw new AssertionError(e); } } - private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws org.whispersystems.libsignal.UntrustedIdentityException, InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, ProtocolUntrustedIdentityException, SelfSendException { + private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, ProtocolUntrustedIdentityException, SelfSendException { SignalServiceCipher cipher = new SignalServiceCipher(new SignalServiceAddress(username), signalProtocolStore, getCertificateValidator()); try { return cipher.decrypt(envelope); @@ -1127,17 +1119,17 @@ class Manager implements Signal { } } - public void retryFailedReceivedMessages(ReceiveMessageHandler handler, boolean ignoreAttachments) { + private void retryFailedReceivedMessages(ReceiveMessageHandler handler, boolean ignoreAttachments) { final File cachePath = new File(getMessageCachePath()); if (!cachePath.exists()) { return; } - for (final File dir : cachePath.listFiles()) { + for (final File dir : Objects.requireNonNull(cachePath.listFiles())) { if (!dir.isDirectory()) { continue; } - for (final File fileEntry : dir.listFiles()) { + for (final File fileEntry : Objects.requireNonNull(dir.listFiles())) { if (!fileEntry.isFile()) { continue; } @@ -1175,7 +1167,7 @@ class Manager implements Signal { public void receiveMessages(long timeout, TimeUnit unit, boolean returnOnTimeout, boolean ignoreAttachments, ReceiveMessageHandler handler) throws IOException { retryFailedReceivedMessages(handler, ignoreAttachments); - final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null, timer); + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(BaseConfig.serviceConfiguration, username, password, deviceId, signalingKey, BaseConfig.USER_AGENT, null, timer); try { if (messagePipe == null) { @@ -1218,7 +1210,7 @@ class Manager implements Signal { } save(); handler.handleMessage(envelope, content, exception); - if (exception == null || !(exception instanceof org.whispersystems.libsignal.UntrustedIdentityException)) { + if (!(exception instanceof org.whispersystems.libsignal.UntrustedIdentityException)) { File cacheFile = null; try { cacheFile = getMessageCacheFile(envelope.getSource(), now, envelope.getTimestamp()); @@ -1442,7 +1434,7 @@ class Manager implements Signal { } } - public File getContactAvatarFile(String number) { + private File getContactAvatarFile(String number) { return new File(avatarsPath, "contact-" + number); } @@ -1457,7 +1449,7 @@ class Manager implements Signal { } } - public File getGroupAvatarFile(byte[] groupId) { + private File getGroupAvatarFile(byte[] groupId) { return new File(avatarsPath, "group-" + Base64.encodeBytes(groupId).replace("/", "_")); } @@ -1481,7 +1473,7 @@ class Manager implements Signal { return retrieveAttachment(pointer, getAttachmentFile(pointer.getId()), true); } - private File retrieveAttachment(SignalServiceAttachmentStream stream, File outputFile) throws IOException, InvalidMessageException { + private File retrieveAttachment(SignalServiceAttachmentStream stream, File outputFile) throws IOException { InputStream input = stream.getInputStream(); try (OutputStream output = new FileOutputStream(outputFile)) { @@ -1510,10 +1502,10 @@ class Manager implements Signal { } } - final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null, timer); + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(BaseConfig.serviceConfiguration, username, password, deviceId, signalingKey, BaseConfig.USER_AGENT, null, timer); File tmpFile = IOUtils.createTempFile(); - try (InputStream input = messageReceiver.retrieveAttachment(pointer, tmpFile, MAX_ATTACHMENT_SIZE)) { + try (InputStream input = messageReceiver.retrieveAttachment(pointer, tmpFile, BaseConfig.MAX_ATTACHMENT_SIZE)) { try (OutputStream output = new FileOutputStream(outputFile)) { byte[] buffer = new byte[4096]; int read; @@ -1536,8 +1528,8 @@ class Manager implements Signal { } private InputStream retrieveAttachmentAsStream(SignalServiceAttachmentPointer pointer, File tmpFile) throws IOException, InvalidMessageException { - final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, username, password, deviceId, signalingKey, USER_AGENT, null, timer); - return messageReceiver.retrieveAttachment(pointer, tmpFile, MAX_ATTACHMENT_SIZE); + final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(BaseConfig.serviceConfiguration, username, password, deviceId, signalingKey, BaseConfig.USER_AGENT, null, timer); + return messageReceiver.retrieveAttachment(pointer, tmpFile, BaseConfig.MAX_ATTACHMENT_SIZE); } private String canonicalizeNumber(String number) throws InvalidNumberException { diff --git a/src/main/java/org/asamk/signal/WhisperTrustStore.java b/src/main/java/org/asamk/signal/manager/WhisperTrustStore.java similarity index 91% rename from src/main/java/org/asamk/signal/WhisperTrustStore.java rename to src/main/java/org/asamk/signal/manager/WhisperTrustStore.java index e9468c2e..185ab599 100644 --- a/src/main/java/org/asamk/signal/WhisperTrustStore.java +++ b/src/main/java/org/asamk/signal/manager/WhisperTrustStore.java @@ -1,4 +1,4 @@ -package org.asamk.signal; +package org.asamk.signal.manager; import org.whispersystems.signalservice.api.push.TrustStore;