mirror of
https://github.com/nextcloud/android.git
synced 2024-11-22 05:05:31 +03:00
Merge pull request #9881 from nextcloud/customCertInEditorWebView
Allow accessing URLs with custom cert in editor
This commit is contained in:
commit
263413d53f
5 changed files with 87 additions and 72 deletions
|
@ -1 +1 @@
|
|||
634
|
||||
633
|
|
@ -1,2 +1,2 @@
|
|||
DO NOT TOUCH; GENERATED BY DRONE
|
||||
<span class="mdl-layout-title">Lint Report: 94 warnings</span>
|
||||
<span class="mdl-layout-title">Lint Report: 93 warnings</span>
|
||||
|
|
|
@ -54,8 +54,6 @@ import android.content.pm.PackageManager;
|
|||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslCertificate;
|
||||
import android.net.http.SslError;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
@ -68,11 +66,9 @@ import android.view.View;
|
|||
import android.view.inputmethod.EditorInfo;
|
||||
import android.webkit.CookieManager;
|
||||
import android.webkit.CookieSyncManager;
|
||||
import android.webkit.SslErrorHandler;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
import android.widget.Toast;
|
||||
|
@ -100,7 +96,6 @@ import com.owncloud.android.lib.common.UserInfo;
|
|||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
|
||||
import com.owncloud.android.lib.common.network.CertificateCombinedException;
|
||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||
import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
|
||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
||||
|
@ -115,6 +110,7 @@ import com.owncloud.android.operations.GetServerInfoOperation;
|
|||
import com.owncloud.android.providers.DocumentsStorageProvider;
|
||||
import com.owncloud.android.services.OperationsService;
|
||||
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
|
||||
import com.owncloud.android.ui.NextcloudWebViewClient;
|
||||
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||
import com.owncloud.android.ui.dialog.IndeterminateProgressDialog;
|
||||
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
|
||||
|
@ -125,13 +121,8 @@ import com.owncloud.android.utils.PermissionUtil;
|
|||
import com.owncloud.android.utils.theme.ThemeDrawableUtils;
|
||||
import com.owncloud.android.utils.theme.ThemeToolbarUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
@ -179,7 +170,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
public static final byte ACTION_CREATE = 0;
|
||||
public static final byte ACTION_UPDATE_EXPIRED_TOKEN = 2; // detected by the app
|
||||
|
||||
private static final String UNTRUSTED_CERT_DIALOG_TAG = "UNTRUSTED_CERT_DIALOG";
|
||||
public static final String UNTRUSTED_CERT_DIALOG_TAG = "UNTRUSTED_CERT_DIALOG";
|
||||
private static final String WAIT_DIALOG_TAG = "WAIT_DIALOG";
|
||||
private static final String KEY_AUTH_IS_FIRST_ATTEMPT_TAG = "KEY_AUTH_IS_FIRST_ATTEMPT";
|
||||
|
||||
|
@ -408,7 +399,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
}
|
||||
|
||||
private void setClient() {
|
||||
accountSetupWebviewBinding.loginWebview.setWebViewClient(new WebViewClient() {
|
||||
accountSetupWebviewBinding.loginWebview.setWebViewClient(new NextcloudWebViewClient(getSupportFragmentManager()) {
|
||||
@Override
|
||||
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
|
||||
webViewFidoU2fBridge.delegateShouldInterceptRequest(view, request);
|
||||
|
@ -447,21 +438,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
getWindow().setNavigationBarColor(primaryColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
||||
X509Certificate cert = getX509CertificateFromError(error);
|
||||
|
||||
try {
|
||||
if (cert != null && NetworkUtils.isCertInKnownServersStore(cert, getApplicationContext())) {
|
||||
handler.proceed();
|
||||
} else {
|
||||
showUntrustedCertDialog(cert, error, handler);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Cert could not be verified");
|
||||
}
|
||||
}
|
||||
|
||||
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
|
||||
accountSetupWebviewBinding.loginWebviewProgressBar.setVisibility(View.GONE);
|
||||
accountSetupWebviewBinding.loginWebview.setVisibility(View.VISIBLE);
|
||||
|
@ -1390,23 +1366,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
return false; // always return false to grant that the software keyboard is hidden anyway
|
||||
}
|
||||
|
||||
/**
|
||||
* Show untrusted cert dialog
|
||||
*/
|
||||
public void showUntrustedCertDialog(X509Certificate x509Certificate, SslError error, SslErrorHandler handler) {
|
||||
// Show a dialog with the certificate info
|
||||
SslUntrustedCertDialog dialog;
|
||||
if (x509Certificate == null) {
|
||||
dialog = SslUntrustedCertDialog.newInstanceForEmptySslError(error, handler);
|
||||
} else {
|
||||
dialog = SslUntrustedCertDialog.newInstanceForFullSslError(x509Certificate, error, handler);
|
||||
}
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
FragmentTransaction ft = fm.beginTransaction();
|
||||
ft.addToBackStack(null);
|
||||
dialog.show(ft, UNTRUSTED_CERT_DIALOG_TAG);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show untrusted cert dialog
|
||||
|
@ -1515,30 +1474,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the X509Certificate from SslError
|
||||
*
|
||||
* @param error SslError
|
||||
* @return X509Certificate from error
|
||||
*/
|
||||
public static X509Certificate getX509CertificateFromError(SslError error) {
|
||||
Bundle bundle = SslCertificate.saveState(error.getCertificate());
|
||||
X509Certificate x509Certificate;
|
||||
byte[] bytes = bundle.getByteArray("x509-certificate");
|
||||
if (bytes == null) {
|
||||
x509Certificate = null;
|
||||
} else {
|
||||
try {
|
||||
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
|
||||
Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
|
||||
x509Certificate = (X509Certificate) cert;
|
||||
} catch (CertificateException e) {
|
||||
x509Certificate = null;
|
||||
}
|
||||
}
|
||||
return x509Certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from SslValidatorDialog when a new server certificate was correctly saved.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package com.owncloud.android.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.net.http.SslCertificate
|
||||
import android.net.http.SslError
|
||||
import android.webkit.SslErrorHandler
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity
|
||||
import com.owncloud.android.lib.common.network.NetworkUtils
|
||||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.X509Certificate
|
||||
|
||||
open class NextcloudWebViewClient(val supportFragmentManager: FragmentManager) : WebViewClient() {
|
||||
|
||||
private val tag: String? = NextcloudWebViewClient::class.simpleName
|
||||
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
@SuppressLint("WebViewClientOnReceivedSslError")
|
||||
override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler, error: SslError?) {
|
||||
val cert = error?.let { getX509CertificateFromError(it) }
|
||||
try {
|
||||
if (NetworkUtils.isCertInKnownServersStore(cert, view?.context?.applicationContext)) {
|
||||
handler.proceed()
|
||||
} else {
|
||||
showUntrustedCertDialog(cert, error, handler)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log_OC.e(tag, "Cert could not be verified")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the X509Certificate from SslError
|
||||
*
|
||||
* @param error SslError
|
||||
* @return X509Certificate from error
|
||||
*/
|
||||
open fun getX509CertificateFromError(error: SslError): X509Certificate? {
|
||||
val bundle = SslCertificate.saveState(error.certificate)
|
||||
val x509Certificate: X509Certificate?
|
||||
val bytes = bundle.getByteArray("x509-certificate")
|
||||
x509Certificate = if (bytes == null) {
|
||||
null
|
||||
} else {
|
||||
try {
|
||||
val certFactory = CertificateFactory.getInstance("X.509")
|
||||
val cert = certFactory.generateCertificate(ByteArrayInputStream(bytes))
|
||||
cert as X509Certificate
|
||||
} catch (e: CertificateException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
return x509Certificate
|
||||
}
|
||||
/**
|
||||
* Show untrusted cert dialog
|
||||
*/
|
||||
private fun showUntrustedCertDialog(
|
||||
x509Certificate: X509Certificate?,
|
||||
error: SslError?,
|
||||
handler: SslErrorHandler?
|
||||
) {
|
||||
// Show a dialog with the certificate info
|
||||
val dialog: SslUntrustedCertDialog = if (x509Certificate == null) {
|
||||
SslUntrustedCertDialog.newInstanceForEmptySslError(error, handler)
|
||||
} else {
|
||||
SslUntrustedCertDialog.newInstanceForFullSslError(x509Certificate, error, handler)
|
||||
}
|
||||
val fm: FragmentManager = supportFragmentManager
|
||||
val ft = fm.beginTransaction()
|
||||
ft.addToBackStack(null)
|
||||
dialog.show(ft, AuthenticatorActivity.UNTRUSTED_CERT_DIALOG_TAG)
|
||||
}
|
||||
}
|
|
@ -31,13 +31,13 @@ import android.view.Window;
|
|||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.ExternalsiteWebviewBinding;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.ui.NextcloudWebViewClient;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.theme.ThemeToolbarUtils;
|
||||
|
||||
|
@ -141,7 +141,7 @@ public class ExternalSiteWebView extends FileActivity {
|
|||
});
|
||||
}
|
||||
|
||||
getWebView().setWebViewClient(new WebViewClient() {
|
||||
getWebView().setWebViewClient(new NextcloudWebViewClient(getSupportFragmentManager()) {
|
||||
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
|
||||
InputStream resources = getResources().openRawResource(R.raw.custom_error);
|
||||
String customError = DisplayUtils.getData(resources);
|
||||
|
|
Loading…
Reference in a new issue