diff --git a/app/build.gradle b/app/build.gradle index faae9e098..f97e27ee6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -228,7 +228,6 @@ android { buildConfigField "String", "CONTENT_PROXY_HOST", "\"contentproxy.signal.org\"" buildConfigField "int", "CONTENT_PROXY_PORT", "443" buildConfigField "String", "SIGNAL_AGENT", "\"OWA\"" - buildConfigField "boolean", "DEV_BUILD", "false" buildConfigField "String", "MRENCLAVE", "\"cd6cfc342937b23b1bdd3bbf9721aa5615ac9ff50a75c5527d441cd3276826c9\"" buildConfigField "String", "KEY_BACKUP_ENCLAVE_NAME", "\"\"" buildConfigField "String", "KEY_BACKUP_MRENCLAVE", "\"a3baab19ef6ce6f34ab9ebb25ba722725ae44a8872dc0ff08ad6d83a9489de87\"" diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/net/GiphyLoader.java b/app/src/main/java/org/thoughtcrime/securesms/giph/net/GiphyLoader.java index eba541edb..f85d2ca28 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/giph/net/GiphyLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/giph/net/GiphyLoader.java @@ -15,6 +15,7 @@ import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.giph.model.GiphyImage; import org.thoughtcrime.securesms.giph.model.GiphyResponse; import org.thoughtcrime.securesms.net.ContentProxySelector; +import org.thoughtcrime.securesms.net.UserAgentInterceptor; import org.thoughtcrime.securesms.util.AsyncLoader; import org.thoughtcrime.securesms.util.JsonUtils; @@ -39,7 +40,10 @@ public abstract class GiphyLoader extends AsyncLoader> { protected GiphyLoader(@NonNull Context context, @Nullable String searchString) { super(context); this.searchString = searchString; - this.client = new OkHttpClient.Builder().proxySelector(new ContentProxySelector()).build(); + this.client = new OkHttpClient.Builder() + .proxySelector(new ContentProxySelector()) + .addInterceptor(new UserAgentInterceptor()) + .build(); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/glide/ChunkedImageUrlLoader.java b/app/src/main/java/org/thoughtcrime/securesms/glide/ChunkedImageUrlLoader.java index 3c3ec2713..08e9fa1bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/glide/ChunkedImageUrlLoader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/glide/ChunkedImageUrlLoader.java @@ -11,6 +11,7 @@ import com.bumptech.glide.load.model.MultiModelLoaderFactory; import org.thoughtcrime.securesms.giph.model.ChunkedImageUrl; import org.thoughtcrime.securesms.net.ContentProxySafetyInterceptor; import org.thoughtcrime.securesms.net.ContentProxySelector; +import org.thoughtcrime.securesms.net.UserAgentInterceptor; import java.io.InputStream; @@ -42,6 +43,7 @@ public class ChunkedImageUrlLoader implements ModelLoader { if (internalClient == null) { internalClient = new OkHttpClient.Builder() .proxySelector(new ContentProxySelector()) + .addInterceptor(new UserAgentInterceptor()) .build(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index 26c3f7dd4..e90ede36a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.net.CompositeRequestController; import org.thoughtcrime.securesms.net.ContentProxySafetyInterceptor; import org.thoughtcrime.securesms.net.ContentProxySelector; import org.thoughtcrime.securesms.net.RequestController; +import org.thoughtcrime.securesms.net.UserAgentInterceptor; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.stickers.StickerRemoteUri; import org.thoughtcrime.securesms.stickers.StickerUrl; @@ -60,6 +61,7 @@ public class LinkPreviewRepository { public LinkPreviewRepository() { this.client = new OkHttpClient.Builder() .proxySelector(new ContentProxySelector()) + .addInterceptor(new UserAgentInterceptor()) .addNetworkInterceptor(new ContentProxySafetyInterceptor()) .cache(null) .build(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitLogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitLogFragment.java index c924856fb..4e2d82f33 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitLogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/SubmitLogFragment.java @@ -57,6 +57,7 @@ import com.annimon.stream.Stream; import org.json.JSONException; import org.json.JSONObject; import org.thoughtcrime.securesms.ApplicationContext; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; @@ -558,17 +559,7 @@ public class SubmitLogFragment extends Fragment { builder.append("Refresh Rate : ").append(String.format(Locale.ENGLISH, "%.2f", FrameRateTracker.getDisplayRefreshRate(context))).append(" hz").append("\n"); builder.append("Average FPS : ").append(String.format(Locale.ENGLISH, "%.2f", ApplicationDependencies.getFrameRateTracker().getRunningAverageFps())).append("\n"); builder.append("First Version: ").append(TextSecurePreferences.getFirstInstallVersion(context)).append("\n"); - builder.append("App : "); - try { - builder.append(pm.getApplicationLabel(pm.getApplicationInfo(context.getPackageName(), 0))) - .append(" ") - .append(pm.getPackageInfo(context.getPackageName(), 0).versionName) - .append(" (") - .append(Util.getManifestApkVersion(context)) - .append(")\n"); - } catch (PackageManager.NameNotFoundException nnfe) { - builder.append("Unknown\n"); - } + builder.append("App : ").append(BuildConfig.VERSION_NAME); return builder; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/net/UserAgentInterceptor.java b/app/src/main/java/org/thoughtcrime/securesms/net/UserAgentInterceptor.java new file mode 100644 index 000000000..c9ddef85f --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/net/UserAgentInterceptor.java @@ -0,0 +1,24 @@ +package org.thoughtcrime.securesms.net; + +import android.os.Build; + +import androidx.annotation.NonNull; + +import org.thoughtcrime.securesms.BuildConfig; + +import java.io.IOException; + +import okhttp3.Interceptor; +import okhttp3.Response; + +public class UserAgentInterceptor implements Interceptor { + + private static final String USER_AGENT = "Signal-Android " + BuildConfig.VERSION_NAME + " (API " + Build.VERSION.SDK_INT + ")"; + + @Override + public Response intercept(@NonNull Chain chain) throws IOException { + return chain.proceed(chain.request().newBuilder() + .header("User-Agent", USER_AGENT) + .build()); + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java index d88433197..c9fa181cb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java @@ -7,6 +7,7 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.provider.ContactsContract; import android.widget.Toast; @@ -17,6 +18,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.preference.CheckBoxPreference; import androidx.preference.Preference; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.logging.Log; @@ -113,17 +115,12 @@ public class AdvancedPreferenceFragment extends CorrectedPreferenceFragment { } private @NonNull String getVersion(@Nullable Context context) { - try { - if (context == null) return ""; + if (context == null) return ""; - String app = context.getString(R.string.app_name); - String version = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; + String app = context.getString(R.string.app_name); + String version = BuildConfig.VERSION_NAME; - return String.format("%s %s", app, version); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, e); - return context.getString(R.string.app_name); - } + return String.format("%s %s", app, version); } private class IdentityPreferenceClickListener implements Preference.OnPreferenceClickListener { diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java index 9139213ed..7b87bbd53 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java +++ b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java @@ -6,6 +6,7 @@ import android.content.Context; import androidx.annotation.Nullable; import org.thoughtcrime.securesms.BuildConfig; +import org.thoughtcrime.securesms.net.UserAgentInterceptor; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; @@ -15,11 +16,14 @@ import org.whispersystems.signalservice.internal.configuration.SignalServiceConf import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl; import org.whispersystems.signalservice.internal.configuration.SignalStorageUrl; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import okhttp3.CipherSuite; import okhttp3.ConnectionSpec; +import okhttp3.Interceptor; import okhttp3.TlsVersion; public class SignalServiceNetworkAccess { @@ -131,39 +135,46 @@ public class SignalServiceNetworkAccess { final SignalStorageUrl omanGoogleStorage = new SignalStorageUrl("https://www.google.com.om/directory", SERVICE_REFLECTOR_HOST, trustStore, GMAIL_CONNECTION_SPEC); final SignalStorageUrl qatarGoogleStorage = new SignalStorageUrl("https://www.google.com.qa/directory", SERVICE_REFLECTOR_HOST, trustStore, GMAIL_CONNECTION_SPEC); + final List interceptors = Collections.singletonList(new UserAgentInterceptor()); + this.censorshipConfiguration = new HashMap() {{ put(COUNTRY_CODE_EGYPT, new SignalServiceConfiguration(new SignalServiceUrl[] {egyptGoogleService, baseGoogleService, baseAndroidService, mapsOneAndroidService, mapsTwoAndroidService, mailAndroidService}, new SignalCdnUrl[] {egyptGoogleCdn, baseAndroidCdn, baseGoogleCdn, mapsOneAndroidCdn, mapsTwoAndroidCdn, mailAndroidCdn, mailAndroidCdn}, new SignalContactDiscoveryUrl[] {egyptGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery}, new SignalKeyBackupServiceUrl[] { signalContactDiscoveryUrl }, - new SignalStorageUrl[] {egyptGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage})); + new SignalStorageUrl[] {egyptGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage}, + interceptors)); put(COUNTRY_CODE_UAE, new SignalServiceConfiguration(new SignalServiceUrl[] {uaeGoogleService, baseAndroidService, baseGoogleService, mapsOneAndroidService, mapsTwoAndroidService, mailAndroidService}, new SignalCdnUrl[] {uaeGoogleCdn, baseAndroidCdn, baseGoogleCdn, mapsOneAndroidCdn, mapsTwoAndroidCdn, mailAndroidCdn}, new SignalContactDiscoveryUrl[] {uaeGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery}, new SignalKeyBackupServiceUrl[] { signalContactDiscoveryUrl }, - new SignalStorageUrl[] {uaeGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage})); + new SignalStorageUrl[] {uaeGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage}, + interceptors)); put(COUNTRY_CODE_OMAN, new SignalServiceConfiguration(new SignalServiceUrl[] {omanGoogleService, baseAndroidService, baseGoogleService, mapsOneAndroidService, mapsTwoAndroidService, mailAndroidService}, new SignalCdnUrl[] {omanGoogleCdn, baseAndroidCdn, baseGoogleCdn, mapsOneAndroidCdn, mapsTwoAndroidCdn, mailAndroidCdn}, new SignalContactDiscoveryUrl[] {omanGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery}, new SignalKeyBackupServiceUrl[] { signalContactDiscoveryUrl }, - new SignalStorageUrl[] {omanGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage})); + new SignalStorageUrl[] {omanGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage}, + interceptors)); put(COUNTRY_CODE_QATAR, new SignalServiceConfiguration(new SignalServiceUrl[] {qatarGoogleService, baseAndroidService, baseGoogleService, mapsOneAndroidService, mapsTwoAndroidService, mailAndroidService}, new SignalCdnUrl[] {qatarGoogleCdn, baseAndroidCdn, baseGoogleCdn, mapsOneAndroidCdn, mapsTwoAndroidCdn, mailAndroidCdn}, new SignalContactDiscoveryUrl[] {qatarGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery}, new SignalKeyBackupServiceUrl[] { signalContactDiscoveryUrl }, - new SignalStorageUrl[] {qatarGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage})); + new SignalStorageUrl[] {qatarGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage}, + interceptors)); }}; this.uncensoredConfiguration = new SignalServiceConfiguration(new SignalServiceUrl[] {new SignalServiceUrl(BuildConfig.SIGNAL_URL, new SignalServiceTrustStore(context))}, new SignalCdnUrl[] {new SignalCdnUrl(BuildConfig.SIGNAL_CDN_URL, new SignalServiceTrustStore(context))}, new SignalContactDiscoveryUrl[] {new SignalContactDiscoveryUrl(BuildConfig.SIGNAL_CONTACT_DISCOVERY_URL, new SignalServiceTrustStore(context))}, new SignalKeyBackupServiceUrl[] { new SignalKeyBackupServiceUrl(BuildConfig.SIGNAL_KEY_BACKUP_URL, new SignalServiceTrustStore(context)) }, - new SignalStorageUrl[] {new SignalStorageUrl(BuildConfig.STORAGE_URL, new SignalServiceTrustStore(context))}); + new SignalStorageUrl[] {new SignalStorageUrl(BuildConfig.STORAGE_URL, new SignalServiceTrustStore(context))}, + interceptors); this.censoredCountries = this.censorshipConfiguration.keySet().toArray(new String[0]); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java index 871c53ce6..1a38f7aea 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java @@ -200,7 +200,8 @@ public class SignalServiceMessageReceiver { WebSocketConnection webSocket = new WebSocketConnection(urls.getSignalServiceUrls()[0].getUrl(), urls.getSignalServiceUrls()[0].getTrustStore(), Optional.of(credentialsProvider), signalAgent, connectivityListener, - sleepTimer); + sleepTimer, + urls.getNetworkInterceptors()); return new SignalServiceMessagePipe(webSocket, Optional.of(credentialsProvider)); } @@ -209,7 +210,8 @@ public class SignalServiceMessageReceiver { WebSocketConnection webSocket = new WebSocketConnection(urls.getSignalServiceUrls()[0].getUrl(), urls.getSignalServiceUrls()[0].getTrustStore(), Optional.absent(), signalAgent, connectivityListener, - sleepTimer); + sleepTimer, + urls.getNetworkInterceptors()); return new SignalServiceMessagePipe(webSocket, Optional.of(credentialsProvider)); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.java index f284f84b5..de6443ff1 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.java @@ -1,6 +1,10 @@ package org.whispersystems.signalservice.internal.configuration; +import java.util.List; + +import okhttp3.Interceptor; + public class SignalServiceConfiguration { private final SignalServiceUrl[] signalServiceUrls; @@ -8,18 +12,21 @@ public class SignalServiceConfiguration { private final SignalContactDiscoveryUrl[] signalContactDiscoveryUrls; private final SignalKeyBackupServiceUrl[] signalKeyBackupServiceUrls; private final SignalStorageUrl[] signalStorageUrls; + private final List networkInterceptors; public SignalServiceConfiguration(SignalServiceUrl[] signalServiceUrls, SignalCdnUrl[] signalCdnUrls, SignalContactDiscoveryUrl[] signalContactDiscoveryUrls, SignalKeyBackupServiceUrl[] signalKeyBackupServiceUrls, - SignalStorageUrl[] signalStorageUrls) + SignalStorageUrl[] signalStorageUrls, + List networkInterceptors) { this.signalServiceUrls = signalServiceUrls; this.signalCdnUrls = signalCdnUrls; this.signalContactDiscoveryUrls = signalContactDiscoveryUrls; this.signalKeyBackupServiceUrls = signalKeyBackupServiceUrls; this.signalStorageUrls = signalStorageUrls; + this.networkInterceptors = networkInterceptors; } public SignalServiceUrl[] getSignalServiceUrls() { @@ -41,4 +48,8 @@ public class SignalServiceConfiguration { public SignalStorageUrl[] getSignalStorageUrls() { return signalStorageUrls; } + + public List getNetworkInterceptors() { + return networkInterceptors; + } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java index 6045f36e4..221985913 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java @@ -94,6 +94,7 @@ import javax.net.ssl.X509TrustManager; import okhttp3.Call; import okhttp3.ConnectionSpec; import okhttp3.Credentials; +import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; @@ -165,7 +166,6 @@ public class PushServiceSocket { private final ConnectionHolder[] contactDiscoveryClients; private final ConnectionHolder[] keyBackupServiceClients; private final ConnectionHolder[] storageClients; - private final OkHttpClient attachmentClient; private final CredentialsProvider credentialsProvider; private final String signalAgent; @@ -174,12 +174,11 @@ public class PushServiceSocket { public PushServiceSocket(SignalServiceConfiguration signalServiceConfiguration, CredentialsProvider credentialsProvider, String signalAgent) { this.credentialsProvider = credentialsProvider; this.signalAgent = signalAgent; - this.serviceClients = createServiceConnectionHolders(signalServiceConfiguration.getSignalServiceUrls()); - this.cdnClients = createConnectionHolders(signalServiceConfiguration.getSignalCdnUrls()); - this.contactDiscoveryClients = createConnectionHolders(signalServiceConfiguration.getSignalContactDiscoveryUrls()); - this.keyBackupServiceClients = createConnectionHolders(signalServiceConfiguration.getSignalKeyBackupServiceUrls()); - this.storageClients = createConnectionHolders(signalServiceConfiguration.getSignalStorageUrls()); - this.attachmentClient = createAttachmentClient(); + this.serviceClients = createServiceConnectionHolders(signalServiceConfiguration.getSignalServiceUrls(), signalServiceConfiguration.getNetworkInterceptors()); + this.cdnClients = createConnectionHolders(signalServiceConfiguration.getSignalCdnUrls(), signalServiceConfiguration.getNetworkInterceptors()); + this.contactDiscoveryClients = createConnectionHolders(signalServiceConfiguration.getSignalContactDiscoveryUrls(), signalServiceConfiguration.getNetworkInterceptors()); + this.keyBackupServiceClients = createConnectionHolders(signalServiceConfiguration.getSignalKeyBackupServiceUrls(), signalServiceConfiguration.getNetworkInterceptors()); + this.storageClients = createConnectionHolders(signalServiceConfiguration.getSignalStorageUrls(), signalServiceConfiguration.getNetworkInterceptors()); this.random = new SecureRandom(); } @@ -1246,62 +1245,49 @@ public class PushServiceSocket { throw new NonSuccessfulResponseCodeException("Response: " + response); } - private ServiceConnectionHolder[] createServiceConnectionHolders(SignalUrl[] urls) { + private ServiceConnectionHolder[] createServiceConnectionHolders(SignalUrl[] urls, List interceptors) { List serviceConnectionHolders = new LinkedList<>(); for (SignalUrl url : urls) { - serviceConnectionHolders.add(new ServiceConnectionHolder(createConnectionClient(url), - createConnectionClient(url), + serviceConnectionHolders.add(new ServiceConnectionHolder(createConnectionClient(url, interceptors), + createConnectionClient(url, interceptors), url.getUrl(), url.getHostHeader())); } return serviceConnectionHolders.toArray(new ServiceConnectionHolder[0]); } - private ConnectionHolder[] createConnectionHolders(SignalUrl[] urls) { + private ConnectionHolder[] createConnectionHolders(SignalUrl[] urls, List interceptors) { List connectionHolders = new LinkedList<>(); for (SignalUrl url : urls) { - connectionHolders.add(new ConnectionHolder(createConnectionClient(url), url.getUrl(), url.getHostHeader())); + connectionHolders.add(new ConnectionHolder(createConnectionClient(url, interceptors), url.getUrl(), url.getHostHeader())); } return connectionHolders.toArray(new ConnectionHolder[0]); } - private OkHttpClient createConnectionClient(SignalUrl url) { + private OkHttpClient createConnectionClient(SignalUrl url, List interceptors) { try { TrustManager[] trustManagers = BlacklistingTrustManager.createFor(url.getTrustStore()); SSLContext context = SSLContext.getInstance("TLS"); context.init(null, trustManagers, null); - return new OkHttpClient.Builder() - .sslSocketFactory(new Tls12SocketFactory(context.getSocketFactory()), (X509TrustManager)trustManagers[0]) - .connectionSpecs(url.getConnectionSpecs().or(Util.immutableList(ConnectionSpec.RESTRICTED_TLS))) - .build(); + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .sslSocketFactory(new Tls12SocketFactory(context.getSocketFactory()), (X509TrustManager)trustManagers[0]) + .connectionSpecs(url.getConnectionSpecs().or(Util.immutableList(ConnectionSpec.RESTRICTED_TLS))); + + for (Interceptor interceptor : interceptors) { + builder.addInterceptor(interceptor); + } + + return builder.build(); } catch (NoSuchAlgorithmException | KeyManagementException e) { throw new AssertionError(e); } } - private OkHttpClient createAttachmentClient() { - try { - SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, null, null); - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init((KeyStore)null); - - return new OkHttpClient.Builder() - .sslSocketFactory(new Tls12SocketFactory(context.getSocketFactory()), - (X509TrustManager)trustManagerFactory.getTrustManagers()[0]) - .connectionSpecs(Util.immutableList(ConnectionSpec.RESTRICTED_TLS)) - .build(); - } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { - throw new AssertionError(e); - } - } - private String getAuthorizationHeader(CredentialsProvider credentialsProvider) { try { String identifier = credentialsProvider.getUuid() != null ? credentialsProvider.getUuid().toString() : credentialsProvider.getE164(); @@ -1364,23 +1350,6 @@ public class PushServiceSocket { private AuthCredentials backupCredentials; } - private static class AttachmentDescriptor { - @JsonProperty - private long id; - - @JsonProperty - private String location; - - public long getId() { - return id; - } - - public String getLocation() { - return location; - } - } - - private static class ConnectionHolder { private final OkHttpClient client; diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java index d07eb91e0..b61099557 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/websocket/WebSocketConnection.java @@ -20,6 +20,7 @@ import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -32,6 +33,7 @@ import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import okhttp3.ConnectionSpec; +import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -57,6 +59,7 @@ public class WebSocketConnection extends WebSocketListener { private final String signalAgent; private final ConnectivityListener listener; private final SleepTimer sleepTimer; + private final List interceptors; private WebSocket client; private KeepAliveSender keepAliveSender; @@ -68,13 +71,15 @@ public class WebSocketConnection extends WebSocketListener { Optional credentialsProvider, String signalAgent, ConnectivityListener listener, - SleepTimer timer) + SleepTimer timer, + List interceptors) { this.trustStore = trustStore; this.credentialsProvider = credentialsProvider; this.signalAgent = signalAgent; this.listener = listener; this.sleepTimer = timer; + this.interceptors = interceptors; this.attempts = 0; this.connected = false; @@ -99,12 +104,17 @@ public class WebSocketConnection extends WebSocketListener { Pair socketFactory = createTlsSocketFactory(trustStore); - OkHttpClient okHttpClient = new OkHttpClient.Builder() - .sslSocketFactory(new Tls12SocketFactory(socketFactory.first()), socketFactory.second()) - .connectionSpecs(Util.immutableList(ConnectionSpec.RESTRICTED_TLS)) - .readTimeout(KEEPALIVE_TIMEOUT_SECONDS + 10, TimeUnit.SECONDS) - .connectTimeout(KEEPALIVE_TIMEOUT_SECONDS + 10, TimeUnit.SECONDS) - .build(); + OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() + .sslSocketFactory(new Tls12SocketFactory(socketFactory.first()), socketFactory.second()) + .connectionSpecs(Util.immutableList(ConnectionSpec.RESTRICTED_TLS)) + .readTimeout(KEEPALIVE_TIMEOUT_SECONDS + 10, TimeUnit.SECONDS) + .connectTimeout(KEEPALIVE_TIMEOUT_SECONDS + 10, TimeUnit.SECONDS); + + for (Interceptor interceptor : interceptors) { + clientBuilder.addInterceptor(interceptor); + } + + OkHttpClient okHttpClient = clientBuilder.build(); Request.Builder requestBuilder = new Request.Builder().url(filledUri);