X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/c72aeed8bba4d5ca873b36b4edb2b8eda9c24ec7..23df85ff909bd1bc8088c429ffd63ea3af6591c6:/lib/src/main/java/org/asamk/signal/manager/Manager.java diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index c4f32460..cb28c45b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -16,6 +16,9 @@ */ package org.asamk.signal.manager; +import org.asamk.signal.manager.config.ServiceConfig; +import org.asamk.signal.manager.config.ServiceEnvironment; +import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.groups.GroupId; import org.asamk.signal.manager.groups.GroupIdV1; import org.asamk.signal.manager.groups.GroupIdV2; @@ -131,7 +134,6 @@ import org.whispersystems.signalservice.api.util.SleepTimer; 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.contacts.crypto.Quote; import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedQuoteException; import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedResponseException; @@ -165,21 +167,20 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -import static org.asamk.signal.manager.ServiceConfig.CDS_MRENCLAVE; -import static org.asamk.signal.manager.ServiceConfig.capabilities; -import static org.asamk.signal.manager.ServiceConfig.getIasKeyStore; +import static org.asamk.signal.manager.config.ServiceConfig.capabilities; public class Manager implements Closeable { private final static Logger logger = LoggerFactory.getLogger(Manager.class); - private final CertificateValidator certificateValidator = new CertificateValidator(ServiceConfig.getUnidentifiedSenderTrustRoot()); + private final CertificateValidator certificateValidator; - private final SignalServiceConfiguration serviceConfiguration; + private final ServiceEnvironmentConfig serviceEnvironmentConfig; private final String userAgent; private SignalAccount account; @@ -189,6 +190,8 @@ public class Manager implements Closeable { private final SignalServiceMessageReceiver messageReceiver; private final ClientZkProfileOperations clientZkProfileOperations; + private final ExecutorService executor = Executors.newCachedThreadPool(); + private SignalServiceMessagePipe messagePipe = null; private SignalServiceMessagePipe unidentifiedMessagePipe = null; @@ -202,16 +205,17 @@ public class Manager implements Closeable { Manager( SignalAccount account, PathConfig pathConfig, - SignalServiceConfiguration serviceConfiguration, + ServiceEnvironmentConfig serviceEnvironmentConfig, String userAgent ) { this.account = account; - this.serviceConfiguration = serviceConfiguration; + this.serviceEnvironmentConfig = serviceEnvironmentConfig; + this.certificateValidator = new CertificateValidator(serviceEnvironmentConfig.getUnidentifiedSenderTrustRoot()); this.userAgent = userAgent; this.groupsV2Operations = capabilities.isGv2() ? new GroupsV2Operations(ClientZkOperations.create( - serviceConfiguration)) : null; + serviceEnvironmentConfig.getSignalServiceConfiguration())) : null; final SleepTimer timer = new UptimeSleepTimer(); - this.accountManager = new SignalServiceAccountManager(serviceConfiguration, + this.accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(), new DynamicCredentialsProvider(account.getUuid(), account.getUsername(), account.getPassword(), @@ -222,11 +226,18 @@ public class Manager implements Closeable { ServiceConfig.AUTOMATIC_NETWORK_RETRY, timer); this.groupsV2Api = accountManager.getGroupsV2Api(); - final KeyBackupService keyBackupService = ServiceConfig.createKeyBackupService(accountManager); + final KeyBackupService keyBackupService = accountManager.getKeyBackupService(ServiceConfig.getIasKeyStore(), + serviceEnvironmentConfig.getKeyBackupConfig().getEnclaveName(), + serviceEnvironmentConfig.getKeyBackupConfig().getServiceId(), + serviceEnvironmentConfig.getKeyBackupConfig().getMrenclave(), + 10); + this.pinHelper = new PinHelper(keyBackupService); - this.clientZkProfileOperations = capabilities.isGv2() ? ClientZkOperations.create(serviceConfiguration) - .getProfileOperations() : null; - this.messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, + this.clientZkProfileOperations = capabilities.isGv2() + ? ClientZkOperations.create(serviceEnvironmentConfig.getSignalServiceConfiguration()) + .getProfileOperations() + : null; + this.messageReceiver = new SignalServiceMessageReceiver(serviceEnvironmentConfig.getSignalServiceConfiguration(), account.getUuid(), account.getUsername(), account.getPassword(), @@ -275,7 +286,7 @@ public class Manager implements Closeable { } public static Manager init( - String username, File settingsPath, SignalServiceConfiguration serviceConfiguration, String userAgent + String username, File settingsPath, ServiceEnvironment serviceEnvironment, String userAgent ) throws IOException, NotRegisteredException { PathConfig pathConfig = PathConfig.createDefault(settingsPath); @@ -289,7 +300,11 @@ public class Manager implements Closeable { throw new NotRegisteredException(); } - return new Manager(account, pathConfig, serviceConfiguration, userAgent); + final ServiceEnvironmentConfig serviceEnvironmentConfig = ServiceConfig.getServiceEnvironmentConfig( + serviceEnvironment, + userAgent); + + return new Manager(account, pathConfig, serviceEnvironmentConfig, userAgent); } public static List getAllLocalUsernames(File settingsPath) { @@ -350,22 +365,33 @@ public class Manager implements Closeable { } /** - * @param avatar if avatar is null the image from the local avatar store is used (if present), - * if it's Optional.absent(), the avatar will be removed + * @param name if null, the previous name will be kept + * @param about if null, the previous about text will be kept + * @param aboutEmoji if null, the previous about emoji will be kept + * @param avatar if avatar is null the image from the local avatar store is used (if present), + * if it's Optional.absent(), the avatar will be removed */ - public void setProfile(String name, Optional avatar) throws IOException { - // TODO - String about = null; - String aboutEmoji = null; + public void setProfile(String name, String about, String aboutEmoji, Optional avatar) throws IOException { + SignalProfileEntry profileEntry = account.getProfileStore().getProfileEntry(getSelfAddress()); + SignalProfile profile = profileEntry == null ? null : profileEntry.getProfile(); + SignalProfile newProfile = new SignalProfile(profile == null ? null : profile.getIdentityKey(), + name != null ? name : profile == null || profile.getName() == null ? "" : profile.getName(), + about != null ? about : profile == null || profile.getAbout() == null ? "" : profile.getAbout(), + aboutEmoji != null + ? aboutEmoji + : profile == null || profile.getAboutEmoji() == null ? "" : profile.getAboutEmoji(), + profile == null ? null : profile.getUnidentifiedAccess(), + account.isUnrestrictedUnidentifiedAccess(), + profile == null ? null : profile.getCapabilities()); try (final StreamDetails streamDetails = avatar == null ? avatarStore.retrieveProfileAvatar(getSelfAddress()) : avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) { accountManager.setVersionedProfile(account.getUuid(), account.getProfileKey(), - name, - about, - aboutEmoji, + newProfile.getName(), + newProfile.getAbout(), + newProfile.getAboutEmoji(), streamDetails); } @@ -377,6 +403,12 @@ public class Manager implements Closeable { avatarStore.deleteProfileAvatar(getSelfAddress()); } } + account.getProfileStore() + .updateProfile(getSelfAddress(), + account.getProfileKey(), + System.currentTimeMillis(), + newProfile, + profileEntry == null ? null : profileEntry.getProfileKeyCredential()); try { sendSyncMessage(SignalServiceSyncMessage.forFetchLatest(SignalServiceSyncMessage.FetchType.LOCAL_PROFILE)); @@ -497,8 +529,7 @@ public class Manager implements Closeable { } private SignalServiceMessageSender createMessageSender() { - final ExecutorService executor = null; - return new SignalServiceMessageSender(serviceConfiguration, + return new SignalServiceMessageSender(serviceEnvironmentConfig.getSignalServiceConfiguration(), account.getUuid(), account.getUsername(), account.getPassword(), @@ -1262,7 +1293,9 @@ public class Manager implements Closeable { private Map getRegisteredUsers(final Set numbersMissingUuid) throws IOException { try { - return accountManager.getRegisteredUsers(getIasKeyStore(), numbersMissingUuid, CDS_MRENCLAVE); + return accountManager.getRegisteredUsers(ServiceConfig.getIasKeyStore(), + numbersMissingUuid, + serviceEnvironmentConfig.getCdsMrenclave()); } catch (Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException | InvalidKeyException e) { throw new IOException(e); } @@ -2502,6 +2535,8 @@ public class Manager implements Closeable { } void close(boolean closeAccount) throws IOException { + executor.shutdown(); + if (messagePipe != null) { messagePipe.shutdown(); messagePipe = null;