import org.whispersystems.signalservice.api.util.StreamDetails;
import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
import org.whispersystems.signalservice.api.util.UuidUtil;
+import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException;
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
-import java.util.Deque;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
private final String attachmentsPath;
private final String avatarsPath;
private final SleepTimer timer = new UptimeSleepTimer();
+ private final SignalServiceConfiguration serviceConfiguration;
+ private final String userAgent;
private SignalAccount account;
private String username;
private SignalServiceMessagePipe messagePipe = null;
private SignalServiceMessagePipe unidentifiedMessagePipe = null;
- public Manager(String username, String settingsPath) {
+ public Manager(String username, String settingsPath, SignalServiceConfiguration serviceConfiguration, String userAgent) {
this.username = username;
this.settingsPath = settingsPath;
this.dataPath = this.settingsPath + "/data";
this.attachmentsPath = this.settingsPath + "/attachments";
this.avatarsPath = this.settingsPath + "/avatars";
-
+ this.serviceConfiguration = serviceConfiguration;
+ this.userAgent = userAgent;
}
public String getUsername() {
}
private SignalServiceAccountManager getSignalServiceAccountManager() {
- return new SignalServiceAccountManager(BaseConfig.serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(), account.getDeviceId(), BaseConfig.USER_AGENT, timer);
+ return new SignalServiceAccountManager(serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(), account.getDeviceId(), userAgent, timer);
}
private IdentityKey getIdentity() {
accountManager = getSignalServiceAccountManager();
if (account.isRegistered()) {
- if (accountManager.getPreKeysCount() < BaseConfig.PREKEY_MINIMUM_COUNT) {
+ if (accountManager.getPreKeysCount() < ServiceConfig.PREKEY_MINIMUM_COUNT) {
refreshPreKeys();
account.save();
}
}
public void updateAccountAttributes() throws IOException {
- accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), account.getRegistrationLock(), getSelfUnidentifiedAccessKey(), false, BaseConfig.capabilities);
+ accountManager.setAccountAttributes(account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, account.getRegistrationLockPin(), account.getRegistrationLock(), getSelfUnidentifiedAccessKey(), false, ServiceConfig.capabilities);
}
public void setProfileName(String name) throws IOException {
}
private List<PreKeyRecord> generatePreKeys() {
- List<PreKeyRecord> records = new ArrayList<>(BaseConfig.PREKEY_BATCH_SIZE);
+ List<PreKeyRecord> records = new ArrayList<>(ServiceConfig.PREKEY_BATCH_SIZE);
final int offset = account.getPreKeyIdOffset();
- for (int i = 0; i < BaseConfig.PREKEY_BATCH_SIZE; i++) {
+ for (int i = 0; i < ServiceConfig.PREKEY_BATCH_SIZE; i++) {
int preKeyId = (offset + i) % Medium.MAX_VALUE;
ECKeyPair keyPair = Curve.generateKeyPair();
PreKeyRecord record = new PreKeyRecord(preKeyId, keyPair);
verificationCode = verificationCode.replace("-", "");
account.setSignalingKey(KeyUtils.createSignalingKey());
// TODO make unrestricted unidentified access configurable
- VerifyAccountResponse response = accountManager.verifyAccountWithCode(verificationCode, account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, pin, null, getSelfUnidentifiedAccessKey(), false, BaseConfig.capabilities);
+ VerifyAccountResponse response = accountManager.verifyAccountWithCode(verificationCode, account.getSignalingKey(), account.getSignalProtocolStore().getLocalRegistrationId(), true, pin, null, getSelfUnidentifiedAccessKey(), false, ServiceConfig.capabilities);
UUID uuid = UuidUtil.parseOrNull(response.getUuid());
// TODO response.isStorageCapable()
private SignalServiceMessageReceiver getMessageReceiver() {
// TODO implement ZkGroup support
final ClientZkProfileOperations clientZkProfileOperations = null;
- return new SignalServiceMessageReceiver(BaseConfig.serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(), account.getDeviceId(), account.getSignalingKey(), BaseConfig.USER_AGENT, null, timer, clientZkProfileOperations);
+ return new SignalServiceMessageReceiver(serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(), account.getDeviceId(), account.getSignalingKey(), userAgent, null, timer, clientZkProfileOperations);
}
private SignalServiceMessageSender getMessageSender() {
// TODO implement ZkGroup support
final ClientZkProfileOperations clientZkProfileOperations = null;
final boolean attachmentsV3 = false;
- return new SignalServiceMessageSender(BaseConfig.serviceConfiguration, account.getUuid(), account.getUsername(), account.getPassword(),
- account.getDeviceId(), account.getSignalProtocolStore(), BaseConfig.USER_AGENT, account.isMultiDevice(), attachmentsV3, Optional.fromNullable(messagePipe), Optional.fromNullable(unidentifiedMessagePipe), Optional.absent(), clientZkProfileOperations);
+ 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);
}
private SignalServiceProfile getRecipientProfile(SignalServiceAddress address, Optional<UnidentifiedAccess> unidentifiedAccess) throws IOException {
final SignalServiceMessageReceiver messageReceiver = getMessageReceiver();
File tmpFile = IOUtils.createTempFile();
- try (InputStream input = messageReceiver.retrieveAttachment(pointer, tmpFile, BaseConfig.MAX_ATTACHMENT_SIZE)) {
+ try (InputStream input = messageReceiver.retrieveAttachment(pointer, tmpFile, ServiceConfig.MAX_ATTACHMENT_SIZE)) {
try (OutputStream output = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[4096];
int read;
private InputStream retrieveAttachmentAsStream(SignalServiceAttachmentPointer pointer, File tmpFile) throws IOException, InvalidMessageException, MissingConfigurationException {
final SignalServiceMessageReceiver messageReceiver = getMessageReceiver();
- return messageReceiver.retrieveAttachment(pointer, tmpFile, BaseConfig.MAX_ATTACHMENT_SIZE);
+ return messageReceiver.retrieveAttachment(pointer, tmpFile, ServiceConfig.MAX_ATTACHMENT_SIZE);
}
@Override
import okhttp3.Dns;
import okhttp3.Interceptor;
-public class BaseConfig {
+public class ServiceConfig {
- 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 ? "signal-cli" : PROJECT_NAME + " " + PROJECT_VERSION;
final static String UNIDENTIFIED_SENDER_TRUST_ROOT = "BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF";
final static int PREKEY_MINIMUM_COUNT = 20;
final static int PREKEY_BATCH_SIZE = 100;
private final static Optional<Dns> dns = Optional.absent();
- private final static Interceptor userAgentInterceptor = chain ->
- chain.proceed(chain.request().newBuilder()
- .header("User-Agent", USER_AGENT)
- .build());
-
- private final static List<Interceptor> interceptors = Collections.singletonList(userAgentInterceptor);
-
private final static byte[] zkGroupServerPublicParams = new byte[]{};
- final static SignalServiceConfiguration serviceConfiguration = new SignalServiceConfiguration(
- new SignalServiceUrl[]{new SignalServiceUrl(URL, TRUST_STORE)},
- makeSignalCdnUrlMapFor(new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)}, new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}),
- new SignalContactDiscoveryUrl[0],
- new SignalKeyBackupServiceUrl[]{new SignalKeyBackupServiceUrl(SIGNAL_KEY_BACKUP_URL, TRUST_STORE)},
- new SignalStorageUrl[]{new SignalStorageUrl(STORAGE_URL, TRUST_STORE)},
- interceptors,
- dns,
- zkGroupServerPublicParams
- );
-
static final SignalServiceProfile.Capabilities capabilities = new SignalServiceProfile.Capabilities(false, false, false);
- private BaseConfig() {
+ public static SignalServiceConfiguration createDefaultServiceConfiguration(String userAgent) {
+ final Interceptor userAgentInterceptor = chain ->
+ chain.proceed(chain.request().newBuilder()
+ .header("User-Agent", userAgent)
+ .build());
+
+ final List<Interceptor> interceptors = Collections.singletonList(userAgentInterceptor);
+
+ return new SignalServiceConfiguration(
+ new SignalServiceUrl[]{new SignalServiceUrl(URL, TRUST_STORE)},
+ makeSignalCdnUrlMapFor(new SignalCdnUrl[]{new SignalCdnUrl(CDN_URL, TRUST_STORE)}, new SignalCdnUrl[]{new SignalCdnUrl(CDN2_URL, TRUST_STORE)}),
+ new SignalContactDiscoveryUrl[0],
+ new SignalKeyBackupServiceUrl[]{new SignalKeyBackupServiceUrl(SIGNAL_KEY_BACKUP_URL, TRUST_STORE)},
+ new SignalStorageUrl[]{new SignalStorageUrl(STORAGE_URL, TRUST_STORE)},
+ interceptors,
+ dns,
+ zkGroupServerPublicParams
+ );
}
private static Map<Integer, SignalCdnUrl[]> makeSignalCdnUrlMapFor(SignalCdnUrl[] cdn0Urls, SignalCdnUrl[] cdn2Urls) {
result.put(2, cdn2Urls);
return Collections.unmodifiableMap(result);
}
+
+ private ServiceConfig() {
+ }
}