1 package org
.asamk
.signal
.manager
.internal
;
3 import org
.asamk
.signal
.manager
.config
.ServiceConfig
;
4 import org
.asamk
.signal
.manager
.config
.ServiceEnvironmentConfig
;
5 import org
.asamk
.signal
.manager
.util
.Utils
;
6 import org
.signal
.libsignal
.metadata
.certificate
.CertificateValidator
;
7 import org
.signal
.libsignal
.net
.Network
;
8 import org
.signal
.libsignal
.zkgroup
.profiles
.ClientZkProfileOperations
;
9 import org
.slf4j
.Logger
;
10 import org
.slf4j
.LoggerFactory
;
11 import org
.whispersystems
.signalservice
.api
.SignalServiceAccountManager
;
12 import org
.whispersystems
.signalservice
.api
.SignalServiceDataStore
;
13 import org
.whispersystems
.signalservice
.api
.SignalServiceMessageReceiver
;
14 import org
.whispersystems
.signalservice
.api
.SignalServiceMessageSender
;
15 import org
.whispersystems
.signalservice
.api
.SignalSessionLock
;
16 import org
.whispersystems
.signalservice
.api
.SignalWebSocket
;
17 import org
.whispersystems
.signalservice
.api
.crypto
.SignalServiceCipher
;
18 import org
.whispersystems
.signalservice
.api
.groupsv2
.ClientZkOperations
;
19 import org
.whispersystems
.signalservice
.api
.groupsv2
.GroupsV2Api
;
20 import org
.whispersystems
.signalservice
.api
.groupsv2
.GroupsV2Operations
;
21 import org
.whispersystems
.signalservice
.api
.link
.LinkDeviceApi
;
22 import org
.whispersystems
.signalservice
.api
.push
.ServiceIdType
;
23 import org
.whispersystems
.signalservice
.api
.push
.SignalServiceAddress
;
24 import org
.whispersystems
.signalservice
.api
.registration
.RegistrationApi
;
25 import org
.whispersystems
.signalservice
.api
.services
.ProfileService
;
26 import org
.whispersystems
.signalservice
.api
.storage
.StorageServiceApi
;
27 import org
.whispersystems
.signalservice
.api
.storage
.StorageServiceRepository
;
28 import org
.whispersystems
.signalservice
.api
.svr
.SecureValueRecovery
;
29 import org
.whispersystems
.signalservice
.api
.util
.CredentialsProvider
;
30 import org
.whispersystems
.signalservice
.api
.util
.UptimeSleepTimer
;
31 import org
.whispersystems
.signalservice
.api
.websocket
.WebSocketFactory
;
32 import org
.whispersystems
.signalservice
.internal
.push
.ProvisioningSocket
;
33 import org
.whispersystems
.signalservice
.internal
.push
.PushServiceSocket
;
34 import org
.whispersystems
.signalservice
.internal
.websocket
.OkHttpWebSocketConnection
;
35 import org
.whispersystems
.signalservice
.internal
.websocket
.WebSocketConnection
;
37 import java
.io
.IOException
;
38 import java
.net
.InetSocketAddress
;
39 import java
.net
.Proxy
;
40 import java
.util
.List
;
41 import java
.util
.Optional
;
42 import java
.util
.concurrent
.ExecutorService
;
43 import java
.util
.function
.Supplier
;
45 public class SignalDependencies
{
47 private static final Logger logger
= LoggerFactory
.getLogger(SignalDependencies
.class);
49 private final Object LOCK
= new Object();
51 private final ServiceEnvironmentConfig serviceEnvironmentConfig
;
52 private final String userAgent
;
53 private final CredentialsProvider credentialsProvider
;
54 private final SignalServiceDataStore dataStore
;
55 private final ExecutorService executor
;
56 private final SignalSessionLock sessionLock
;
58 private boolean allowStories
= true;
60 private SignalServiceAccountManager accountManager
;
61 private GroupsV2Api groupsV2Api
;
62 private RegistrationApi registrationApi
;
63 private LinkDeviceApi linkDeviceApi
;
64 private StorageServiceApi storageServiceApi
;
65 private GroupsV2Operations groupsV2Operations
;
66 private ClientZkOperations clientZkOperations
;
68 private PushServiceSocket pushServiceSocket
;
69 private ProvisioningSocket provisioningSocket
;
70 private Network libSignalNetwork
;
71 private SignalWebSocket signalWebSocket
;
72 private SignalServiceMessageReceiver messageReceiver
;
73 private SignalServiceMessageSender messageSender
;
75 private List
<SecureValueRecovery
> secureValueRecovery
;
76 private ProfileService profileService
;
79 final ServiceEnvironmentConfig serviceEnvironmentConfig
,
80 final String userAgent
,
81 final CredentialsProvider credentialsProvider
,
82 final SignalServiceDataStore dataStore
,
83 final ExecutorService executor
,
84 final SignalSessionLock sessionLock
86 this.serviceEnvironmentConfig
= serviceEnvironmentConfig
;
87 this.userAgent
= userAgent
;
88 this.credentialsProvider
= credentialsProvider
;
89 this.dataStore
= dataStore
;
90 this.executor
= executor
;
91 this.sessionLock
= sessionLock
;
94 public void resetAfterAddressChange() {
95 if (this.pushServiceSocket
!= null) {
96 this.pushServiceSocket
.close();
97 this.pushServiceSocket
= null;
98 this.accountManager
= null;
99 this.messageReceiver
= null;
100 this.messageSender
= null;
101 this.profileService
= null;
102 this.groupsV2Api
= null;
103 this.registrationApi
= null;
104 this.secureValueRecovery
= null;
106 getSignalWebSocket().forceNewWebSockets();
110 * This method needs to be called before the first websocket is created
112 public void setAllowStories(final boolean allowStories
) {
113 this.allowStories
= allowStories
;
116 public ServiceEnvironmentConfig
getServiceEnvironmentConfig() {
117 return serviceEnvironmentConfig
;
120 public SignalSessionLock
getSessionLock() {
124 public PushServiceSocket
getPushServiceSocket() {
125 return getOrCreate(() -> pushServiceSocket
,
126 () -> pushServiceSocket
= new PushServiceSocket(serviceEnvironmentConfig
.signalServiceConfiguration(),
129 getClientZkProfileOperations(),
130 ServiceConfig
.AUTOMATIC_NETWORK_RETRY
));
133 public ProvisioningSocket
getProvisioningSocket() {
134 return getOrCreate(() -> provisioningSocket
,
135 () -> provisioningSocket
= new ProvisioningSocket(getServiceEnvironmentConfig().signalServiceConfiguration(),
139 public Network
getLibSignalNetwork() {
140 return getOrCreate(() -> libSignalNetwork
, () -> {
141 libSignalNetwork
= new Network(serviceEnvironmentConfig
.netEnvironment(), userAgent
);
142 setSignalNetworkProxy(libSignalNetwork
);
146 private void setSignalNetworkProxy(Network libSignalNetwork
) {
147 final var proxy
= Utils
.getHttpsProxy();
148 if (proxy
.address() instanceof InetSocketAddress addr
) {
149 switch (proxy
.type()) {
150 case Proxy
.Type
.DIRECT
-> {
152 case Proxy
.Type
.HTTP
-> {
154 libSignalNetwork
.setProxy("http", addr
.getHostName(), addr
.getPort(), null, null);
155 } catch (IOException e
) {
156 logger
.warn("Failed to set http proxy", e
);
159 case Proxy
.Type
.SOCKS
-> {
161 libSignalNetwork
.setProxy("socks", addr
.getHostName(), addr
.getPort(), null, null);
162 } catch (IOException e
) {
163 logger
.warn("Failed to set socks proxy", e
);
170 public SignalServiceAccountManager
getAccountManager() {
171 return getOrCreate(() -> accountManager
,
172 () -> accountManager
= new SignalServiceAccountManager(getPushServiceSocket(),
173 getProvisioningSocket(),
174 getGroupsV2Operations()));
177 public SignalServiceAccountManager
createUnauthenticatedAccountManager(String number
, String password
) {
178 return SignalServiceAccountManager
.createWithStaticCredentials(getServiceEnvironmentConfig().signalServiceConfiguration(),
182 SignalServiceAddress
.DEFAULT_DEVICE_ID
,
185 ServiceConfig
.AUTOMATIC_NETWORK_RETRY
,
186 ServiceConfig
.GROUP_MAX_SIZE
);
189 public GroupsV2Api
getGroupsV2Api() {
190 return getOrCreate(() -> groupsV2Api
, () -> groupsV2Api
= getAccountManager().getGroupsV2Api());
193 public RegistrationApi
getRegistrationApi() {
194 return getOrCreate(() -> registrationApi
, () -> registrationApi
= getAccountManager().getRegistrationApi());
197 public LinkDeviceApi
getLinkDeviceApi() {
198 return getOrCreate(() -> linkDeviceApi
, () -> linkDeviceApi
= new LinkDeviceApi(getPushServiceSocket()));
201 private StorageServiceApi
getStorageServiceApi() {
202 return getOrCreate(() -> storageServiceApi
,
203 () -> storageServiceApi
= new StorageServiceApi(getPushServiceSocket()));
206 public StorageServiceRepository
getStorageServiceRepository() {
207 return new StorageServiceRepository(getStorageServiceApi());
210 public GroupsV2Operations
getGroupsV2Operations() {
211 return getOrCreate(() -> groupsV2Operations
,
212 () -> groupsV2Operations
= new GroupsV2Operations(ClientZkOperations
.create(serviceEnvironmentConfig
.signalServiceConfiguration()),
213 ServiceConfig
.GROUP_MAX_SIZE
));
216 private ClientZkOperations
getClientZkOperations() {
217 return getOrCreate(() -> clientZkOperations
,
218 () -> clientZkOperations
= ClientZkOperations
.create(serviceEnvironmentConfig
.signalServiceConfiguration()));
221 private ClientZkProfileOperations
getClientZkProfileOperations() {
222 final var clientZkOperations
= getClientZkOperations();
223 return clientZkOperations
.getProfileOperations();
226 public SignalWebSocket
getSignalWebSocket() {
227 return getOrCreate(() -> signalWebSocket
, () -> {
228 final var timer
= new UptimeSleepTimer();
229 final var healthMonitor
= new SignalWebSocketHealthMonitor(timer
);
230 final var webSocketFactory
= new WebSocketFactory() {
232 public WebSocketConnection
createWebSocket() {
233 return new OkHttpWebSocketConnection("normal",
234 serviceEnvironmentConfig
.signalServiceConfiguration(),
235 Optional
.of(credentialsProvider
),
242 public WebSocketConnection
createUnidentifiedWebSocket() {
243 return new OkHttpWebSocketConnection("unidentified",
244 serviceEnvironmentConfig
.signalServiceConfiguration(),
251 signalWebSocket
= new SignalWebSocket(webSocketFactory
);
252 healthMonitor
.monitor(signalWebSocket
);
256 public SignalServiceMessageReceiver
getMessageReceiver() {
257 return getOrCreate(() -> messageReceiver
,
258 () -> messageReceiver
= new SignalServiceMessageReceiver(getPushServiceSocket()));
261 public SignalServiceMessageSender
getMessageSender() {
262 return getOrCreate(() -> messageSender
,
263 () -> messageSender
= new SignalServiceMessageSender(getPushServiceSocket(),
266 getSignalWebSocket(),
269 ServiceConfig
.MAX_ENVELOPE_SIZE
));
272 public List
<SecureValueRecovery
> getSecureValueRecovery() {
273 return getOrCreate(() -> secureValueRecovery
,
274 () -> secureValueRecovery
= serviceEnvironmentConfig
.svr2Mrenclaves()
276 .map(mr
-> (SecureValueRecovery
) getAccountManager().getSecureValueRecoveryV2(mr
))
280 public ProfileService
getProfileService() {
281 return getOrCreate(() -> profileService
,
282 () -> profileService
= new ProfileService(getClientZkProfileOperations(),
283 getMessageReceiver(),
284 getSignalWebSocket()));
287 public SignalServiceCipher
getCipher(ServiceIdType serviceIdType
) {
288 final var certificateValidator
= new CertificateValidator(serviceEnvironmentConfig
.unidentifiedSenderTrustRoot());
289 final var address
= new SignalServiceAddress(credentialsProvider
.getAci(), credentialsProvider
.getE164());
290 final var deviceId
= credentialsProvider
.getDeviceId();
291 return new SignalServiceCipher(address
,
293 serviceIdType
== ServiceIdType
.ACI ? dataStore
.aci() : dataStore
.pni(),
295 certificateValidator
);
298 private <T
> T
getOrCreate(Supplier
<T
> supplier
, Callable creator
) {
299 var value
= supplier
.get();
304 synchronized (LOCK
) {
305 value
= supplier
.get();
310 return supplier
.get();
314 private interface Callable
{