Added SSL Validation Override and CA Selection
- Added fields to login page to a) disable ssl validation or b) select a custom Certificate Authority certificate to use with the server. - Changed visibility of widgets on login page from INVISIBLE to GONE so they don't take up space while hidden (since this was causing weird spacing issues with the new fields). - Added state to settings to store ssl validation choice or certificate data. - Added fields to various HTTP methods to disable ssl validation or set valid certificate authority if either setting is enabled.
This commit is contained in:
@@ -34,6 +34,8 @@ public class Settings {
|
||||
public void clear() {
|
||||
url(null);
|
||||
token(null);
|
||||
validateSSL(true);
|
||||
cert(null);
|
||||
}
|
||||
|
||||
public void user(String name, boolean admin) {
|
||||
@@ -57,4 +59,13 @@ public class Settings {
|
||||
public void serverVersion(String version) {
|
||||
sharedPreferences.edit().putString("version", version).apply();
|
||||
}
|
||||
|
||||
// Default to always validating SSL.
|
||||
public boolean validateSSL() { return sharedPreferences.getBoolean("validateSSL", true); }
|
||||
|
||||
public void validateSSL(boolean validateSSL) { sharedPreferences.edit().putBoolean("validateSSL", validateSSL).apply(); }
|
||||
|
||||
public String cert() { return sharedPreferences.getString("cert", null); }
|
||||
|
||||
public void cert(String cert) { sharedPreferences.edit().putString("cert", cert).apply(); }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.gotify;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -7,14 +8,30 @@ import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.format.DateUtils;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.github.gotify.client.ApiClient;
|
||||
import com.github.gotify.client.JSON;
|
||||
import com.github.gotify.log.Log;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.squareup.picasso.Picasso;
|
||||
import com.squareup.picasso.Target;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okio.Buffer;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
|
||||
public class Utils {
|
||||
public static void showSnackBar(Activity activity, String message) {
|
||||
View rootView = activity.getWindow().getDecorView().findViewById(android.R.id.content);
|
||||
@@ -52,4 +69,110 @@ public class Utils {
|
||||
public interface DrawableReceiver {
|
||||
void loaded(Drawable drawable);
|
||||
}
|
||||
|
||||
public static InputStream stringToInputStream(String str) {
|
||||
if (str == null) return null;
|
||||
return new Buffer()
|
||||
.writeUtf8(str)
|
||||
.inputStream();
|
||||
}
|
||||
|
||||
public static String readFileFromStream(@NonNull InputStream inputStream) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String currentLine;
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
while ((currentLine = reader.readLine()) != null) {
|
||||
sb.append(currentLine).append("\n");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException("failed to read input");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/////////////////////////
|
||||
///// SSL Utilities /////
|
||||
/////////////////////////
|
||||
public static Certificate parseCertificate(String cert) {
|
||||
try {
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
|
||||
|
||||
return certificateFactory.generateCertificate(Utils.stringToInputStream(cert));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("certificate is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
public static class SSLSettings {
|
||||
boolean validateSSL;
|
||||
String cert;
|
||||
|
||||
public SSLSettings(boolean validateSSL, String cert) {
|
||||
this.validateSSL = validateSSL;
|
||||
this.cert = cert;
|
||||
}
|
||||
}
|
||||
|
||||
// TrustManager that trusts all SSL Certs
|
||||
private static final TrustManager trustAll = new X509TrustManager() {
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; }
|
||||
};
|
||||
|
||||
public static void applySslSettings(OkHttpClient.Builder builder, SSLSettings settings) {
|
||||
// Modified from ApiClient.applySslSettings in the client package.
|
||||
|
||||
try {
|
||||
TrustManager[] trustManagers = null;
|
||||
HostnameVerifier hostnameVerifier = null;
|
||||
if (!settings.validateSSL) {
|
||||
trustManagers = new TrustManager[]{ trustAll };
|
||||
hostnameVerifier = (hostname, session) -> true;
|
||||
} else if (settings.cert != null) {
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(stringToInputStream(settings.cert));
|
||||
if (certificates.isEmpty()) {
|
||||
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
|
||||
}
|
||||
KeyStore caKeyStore = newEmptyKeyStore();
|
||||
int index = 0;
|
||||
for (Certificate certificate : certificates) {
|
||||
String certificateAlias = "ca" + Integer.toString(index++);
|
||||
caKeyStore.setCertificateEntry(certificateAlias, certificate);
|
||||
}
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
trustManagerFactory.init(caKeyStore);
|
||||
trustManagers = trustManagerFactory.getTrustManagers();
|
||||
}
|
||||
|
||||
if (trustManagers != null && trustManagers.length > 0) {
|
||||
SSLContext context = SSLContext.getInstance("TLS");
|
||||
context.init(new KeyManager[]{}, trustManagers, new SecureRandom());
|
||||
builder.sslSocketFactory(context.getSocketFactory(), (X509TrustManager) trustManagers[0]);
|
||||
}
|
||||
|
||||
if (hostnameVerifier != null) builder.hostnameVerifier(hostnameVerifier);
|
||||
} catch (Exception e) {
|
||||
// We shouldn't have issues since the cert is verified on login.
|
||||
Log.e("Failed to apply SSL settings", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static KeyStore newEmptyKeyStore() throws GeneralSecurityException {
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
keyStore.load(null, null);
|
||||
return keyStore;
|
||||
} catch (IOException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gotify.api;
|
||||
|
||||
import com.github.gotify.Settings;
|
||||
import com.github.gotify.Utils;
|
||||
import com.github.gotify.client.ApiClient;
|
||||
import com.github.gotify.client.api.UserApi;
|
||||
import com.github.gotify.client.api.VersionApi;
|
||||
@@ -8,14 +9,16 @@ import com.github.gotify.client.auth.ApiKeyAuth;
|
||||
import com.github.gotify.client.auth.HttpBasicAuth;
|
||||
|
||||
public class ClientFactory {
|
||||
public static ApiClient unauthorized(String baseUrl) {
|
||||
public static ApiClient unauthorized(String baseUrl, boolean validateSSL, String cert) {
|
||||
ApiClient client = new ApiClient();
|
||||
client.setVerifyingSsl(validateSSL);
|
||||
client.setSslCaCert(Utils.stringToInputStream(cert));
|
||||
client.setBasePath(baseUrl);
|
||||
return client;
|
||||
}
|
||||
|
||||
public static ApiClient basicAuth(String baseUrl, String username, String password) {
|
||||
ApiClient client = unauthorized(baseUrl);
|
||||
public static ApiClient basicAuth(String baseUrl, boolean validateSSL, String cert, String username, String password) {
|
||||
ApiClient client = unauthorized(baseUrl, validateSSL, cert);
|
||||
HttpBasicAuth auth = (HttpBasicAuth) client.getAuthentication("basicAuth");
|
||||
auth.setUsername(username);
|
||||
auth.setPassword(password);
|
||||
@@ -23,18 +26,18 @@ public class ClientFactory {
|
||||
return client;
|
||||
}
|
||||
|
||||
public static ApiClient clientToken(String baseUrl, String token) {
|
||||
ApiClient client = unauthorized(baseUrl);
|
||||
public static ApiClient clientToken(String baseUrl, boolean validateSSL, String cert, String token) {
|
||||
ApiClient client = unauthorized(baseUrl, validateSSL, cert);
|
||||
ApiKeyAuth tokenAuth = (ApiKeyAuth) client.getAuthentication("clientTokenHeader");
|
||||
tokenAuth.setApiKey(token);
|
||||
return client;
|
||||
}
|
||||
|
||||
public static VersionApi versionApi(String baseUrl) {
|
||||
return new VersionApi(unauthorized(baseUrl));
|
||||
public static VersionApi versionApi(String baseUrl, boolean validateSSL, String cert) {
|
||||
return new VersionApi(unauthorized(baseUrl, validateSSL, cert));
|
||||
}
|
||||
|
||||
public static UserApi userApiWithToken(Settings settings) {
|
||||
return new UserApi(clientToken(settings.url(), settings.token()));
|
||||
return new UserApi(clientToken(settings.url(), settings.validateSSL(), settings.cert(), settings.token()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ public class InitializationActivity extends AppCompatActivity {
|
||||
private void requestVersion(
|
||||
final Callback.SuccessCallback<VersionInfo> callback,
|
||||
final Callback.ErrorCallback errorCallback) {
|
||||
VersionApi versionApi = ClientFactory.versionApi(settings.url());
|
||||
VersionApi versionApi = ClientFactory.versionApi(settings.url(), settings.validateSSL(), settings.cert());
|
||||
Api.withLogging(versionApi::getVersionAsync)
|
||||
.handleInUIThread(this, callback, errorCallback);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
package com.github.gotify.login;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.*;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.OnTextChanged;
|
||||
import butterknife.*;
|
||||
import com.github.gotify.R;
|
||||
import com.github.gotify.Settings;
|
||||
import com.github.gotify.Utils;
|
||||
@@ -31,8 +29,15 @@ import com.github.gotify.log.Log;
|
||||
import com.github.gotify.log.UncaughtExceptionHandler;
|
||||
import com.squareup.okhttp.HttpUrl;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
// return value from startActivityForResult when choosing a certificate
|
||||
private final int FILE_SELECT_CODE = 1;
|
||||
|
||||
@BindView(R.id.username)
|
||||
EditText usernameField;
|
||||
|
||||
@@ -42,6 +47,21 @@ public class LoginActivity extends AppCompatActivity {
|
||||
@BindView(R.id.password)
|
||||
EditText passwordField;
|
||||
|
||||
@BindView(R.id.showAdvanced)
|
||||
Button toggleAdvanced;
|
||||
|
||||
@BindView(R.id.disableValidateSSL)
|
||||
CheckBox disableSSLValidationCheckBox;
|
||||
|
||||
@BindView(R.id.or)
|
||||
TextView orTextView;
|
||||
|
||||
@BindView(R.id.selectCACertificate)
|
||||
Button selectCACertificate;
|
||||
|
||||
@BindView(R.id.caFile)
|
||||
TextView caFileName;
|
||||
|
||||
@BindView(R.id.checkurl)
|
||||
Button checkUrlButton;
|
||||
|
||||
@@ -54,8 +74,13 @@ public class LoginActivity extends AppCompatActivity {
|
||||
@BindView(R.id.login_progress)
|
||||
ProgressBar loginProgress;
|
||||
|
||||
private boolean showAdvanced = false;
|
||||
|
||||
private Settings settings;
|
||||
|
||||
private boolean disableSSLValidation;
|
||||
private String caCertContents;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -68,9 +93,9 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
@OnTextChanged(R.id.gotify_url)
|
||||
public void onUrlChange() {
|
||||
usernameField.setVisibility(View.INVISIBLE);
|
||||
passwordField.setVisibility(View.INVISIBLE);
|
||||
loginButton.setVisibility(View.INVISIBLE);
|
||||
usernameField.setVisibility(View.GONE);
|
||||
passwordField.setVisibility(View.GONE);
|
||||
loginButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@OnClick(R.id.checkurl)
|
||||
@@ -82,18 +107,81 @@ public class LoginActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
checkUrlProgress.setVisibility(View.VISIBLE);
|
||||
checkUrlButton.setVisibility(View.INVISIBLE);
|
||||
checkUrlButton.setVisibility(View.GONE);
|
||||
|
||||
final String fixedUrl = url.endsWith("/") ? url.substring(0, url.length() - 1) : url;
|
||||
|
||||
Api.withLogging(ClientFactory.versionApi(fixedUrl)::getVersionAsync)
|
||||
Api.withLogging(ClientFactory.versionApi(fixedUrl, !disableSSLValidation, caCertContents)::getVersionAsync)
|
||||
.handleInUIThread(this, onValidUrl(fixedUrl), onInvalidUrl(fixedUrl));
|
||||
}
|
||||
|
||||
@OnClick(R.id.showAdvanced)
|
||||
void doShowAdvanced() {
|
||||
showAdvanced = !showAdvanced;
|
||||
disableSSLValidationCheckBox.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
selectCACertificate.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
orTextView.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
caFileName.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@OnCheckedChanged(R.id.disableValidateSSL)
|
||||
void doChangeDisableValidateSSL(boolean disable) {
|
||||
// temporarily set the ssl validation (don't store to settings until they decide to login)
|
||||
disableSSLValidation = disable;
|
||||
}
|
||||
|
||||
@OnClick(R.id.selectCACertificate)
|
||||
void doSelectCACertificate() {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
// we don't really care what kind of file it is as long as we can parse it
|
||||
intent.setType("*/*");
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
|
||||
try {
|
||||
startActivityForResult(Intent.createChooser(intent, getString(R.string.select_ca_file)), FILE_SELECT_CODE);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
// case for user not having a file browser installed
|
||||
Utils.showSnackBar(LoginActivity.this, getString(R.string.please_install_file_browser));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
try {
|
||||
if (requestCode == FILE_SELECT_CODE) {
|
||||
if (resultCode != RESULT_OK) {
|
||||
throw new IllegalArgumentException(String.format("result was %d", resultCode));
|
||||
} else if (data == null) {
|
||||
throw new IllegalArgumentException("file path was null");
|
||||
}
|
||||
|
||||
Uri uri = data.getData();
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException("file path was null");
|
||||
}
|
||||
|
||||
InputStream fileStream = getContentResolver().openInputStream(uri);
|
||||
if (fileStream == null) {
|
||||
throw new IllegalArgumentException("file path was invalid");
|
||||
}
|
||||
|
||||
String contents = Utils.readFileFromStream(fileStream);
|
||||
Certificate ca = Utils.parseCertificate(contents);
|
||||
|
||||
caFileName.setText(((X509Certificate) ca).getSubjectDN().getName());
|
||||
// temporarily set the contents (don't store to settings until they decide to login)
|
||||
caCertContents = contents;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Utils.showSnackBar(LoginActivity.this, getString(R.string.select_ca_failed, e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private Callback.SuccessCallback<VersionInfo> onValidUrl(String url) {
|
||||
return (version) -> {
|
||||
settings.url(url);
|
||||
checkUrlProgress.setVisibility(View.INVISIBLE);
|
||||
checkUrlProgress.setVisibility(View.GONE);
|
||||
checkUrlButton.setVisibility(View.VISIBLE);
|
||||
checkUrlButton.setText(getString(R.string.found_gotify_version, version.getVersion()));
|
||||
usernameField.setVisibility(View.VISIBLE);
|
||||
@@ -105,7 +193,7 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
private Callback.ErrorCallback onInvalidUrl(String url) {
|
||||
return (exception) -> {
|
||||
checkUrlProgress.setVisibility(View.INVISIBLE);
|
||||
checkUrlProgress.setVisibility(View.GONE);
|
||||
checkUrlButton.setVisibility(View.VISIBLE);
|
||||
Utils.showSnackBar(LoginActivity.this, versionError(url, exception));
|
||||
};
|
||||
@@ -116,17 +204,17 @@ public class LoginActivity extends AppCompatActivity {
|
||||
String username = usernameField.getText().toString();
|
||||
String password = passwordField.getText().toString();
|
||||
|
||||
loginButton.setVisibility(View.INVISIBLE);
|
||||
loginButton.setVisibility(View.GONE);
|
||||
loginProgress.setVisibility(View.VISIBLE);
|
||||
|
||||
ApiClient client = ClientFactory.basicAuth(settings.url(), username, password);
|
||||
ApiClient client = ClientFactory.basicAuth(settings.url(), !disableSSLValidation, caCertContents, username, password);
|
||||
Api.withLogging(new UserApi(client)::currentUserAsync)
|
||||
.handleInUIThread(this, (user) -> newClientDialog(client), this::onInvalidLogin);
|
||||
}
|
||||
|
||||
private void onInvalidLogin(ApiException e) {
|
||||
loginButton.setVisibility(View.VISIBLE);
|
||||
loginProgress.setVisibility(View.INVISIBLE);
|
||||
loginProgress.setVisibility(View.GONE);
|
||||
Utils.showSnackBar(this, getString(R.string.wronguserpw));
|
||||
}
|
||||
|
||||
@@ -153,6 +241,10 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
private void onCreatedClient(Client client) {
|
||||
settings.token(client.getToken());
|
||||
// Set the final ssl validation status and / or cert
|
||||
settings.validateSSL(!disableSSLValidation);
|
||||
settings.cert(caCertContents);
|
||||
|
||||
Utils.showSnackBar(this, getString(R.string.created_client));
|
||||
startActivity(new Intent(this, InitializationActivity.class));
|
||||
finish();
|
||||
@@ -160,12 +252,12 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
private void onFailedToCreateClient(ApiException e) {
|
||||
Utils.showSnackBar(this, getString(R.string.create_client_failed));
|
||||
loginProgress.setVisibility(View.INVISIBLE);
|
||||
loginProgress.setVisibility(View.GONE);
|
||||
loginButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void onCancelClientDialog(DialogInterface dialog, int which) {
|
||||
loginProgress.setVisibility(View.INVISIBLE);
|
||||
loginProgress.setVisibility(View.GONE);
|
||||
loginButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public class MessagesActivity extends AppCompatActivity
|
||||
Log.i("Entering " + getClass().getSimpleName());
|
||||
settings = new Settings(this);
|
||||
|
||||
client = ClientFactory.clientToken(settings.url(), settings.token());
|
||||
client = ClientFactory.clientToken(settings.url(), settings.validateSSL(), settings.cert(), settings.token());
|
||||
appsHolder = new ApplicationHolder(this, client);
|
||||
appsHolder.onUpdate(() -> onUpdateApps(appsHolder.get()));
|
||||
appsHolder.request();
|
||||
@@ -401,7 +401,7 @@ public class MessagesActivity extends AppCompatActivity
|
||||
@Override
|
||||
protected Void doInBackground(Void... ignore) {
|
||||
TokenApi api =
|
||||
new TokenApi(ClientFactory.clientToken(settings.url(), settings.token()));
|
||||
new TokenApi(ClientFactory.clientToken(settings.url(), settings.validateSSL(), settings.cert(), settings.token()));
|
||||
stopService(new Intent(MessagesActivity.this, WebSocketService.class));
|
||||
try {
|
||||
List<Client> clients = api.getClients();
|
||||
|
||||
@@ -15,15 +15,9 @@ import okhttp3.WebSocket;
|
||||
import okhttp3.WebSocketListener;
|
||||
|
||||
public class WebSocketConnection {
|
||||
private OkHttpClient client;
|
||||
private static final JSON gson = Utils.json();
|
||||
|
||||
private final OkHttpClient client =
|
||||
new OkHttpClient.Builder()
|
||||
.readTimeout(0, TimeUnit.MILLISECONDS)
|
||||
.pingInterval(1, TimeUnit.MINUTES)
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
private final Handler handler = new Handler();
|
||||
private int errorCount = 0;
|
||||
|
||||
@@ -38,7 +32,15 @@ public class WebSocketConnection {
|
||||
private Runnable onReconnected;
|
||||
private boolean isClosed;
|
||||
|
||||
WebSocketConnection(String baseUrl, String token) {
|
||||
WebSocketConnection(String baseUrl, boolean validateSSL, String cert, String token) {
|
||||
OkHttpClient.Builder builder = new OkHttpClient.Builder()
|
||||
.readTimeout(0, TimeUnit.MILLISECONDS)
|
||||
.pingInterval(1, TimeUnit.MINUTES)
|
||||
.connectTimeout(10, TimeUnit.SECONDS);
|
||||
Utils.applySslSettings(builder, new Utils.SSLSettings(validateSSL, cert));
|
||||
|
||||
client = builder.build();
|
||||
|
||||
this.baseUrl = baseUrl;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class WebSocketService extends Service {
|
||||
super.onCreate();
|
||||
settings = new Settings(this);
|
||||
missingMessageUtil =
|
||||
new MissedMessageUtil(ClientFactory.clientToken(settings.url(), settings.token()));
|
||||
new MissedMessageUtil(ClientFactory.clientToken(settings.url(), settings.validateSSL(), settings.cert(), settings.token()));
|
||||
Log.i("Create " + getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class WebSocketService extends Service {
|
||||
}
|
||||
|
||||
connection =
|
||||
new WebSocketConnection(settings.url(), settings.token())
|
||||
new WebSocketConnection(settings.url(), settings.validateSSL(), settings.cert(), settings.token())
|
||||
.onOpen(this::onOpen)
|
||||
.onClose(() -> foreground(getString(R.string.websocket_closed)))
|
||||
.onBadRequest(this::onBadRequest)
|
||||
|
||||
Reference in New Issue
Block a user