From: David A. Velasco Date: Tue, 11 Mar 2014 10:39:19 +0000 (+0100) Subject: Ssl-error dialogs joint in a single one that uses different adapters to update its... X-Git-Tag: oc-android-1.5.5~15^2~3^2 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/8c6f415ed47c3c456be4d9d4f391582d368b3278 Ssl-error dialogs joint in a single one that uses different adapters to update its view depending on the classes providing the information --- diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java index f18ff2ab..2fabc330 100644 --- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java +++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java @@ -48,6 +48,7 @@ import android.view.View.OnFocusChangeListener; import android.view.View.OnTouchListener; import android.view.Window; import android.view.inputmethod.EditorInfo; +import android.webkit.SslErrorHandler; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; @@ -64,6 +65,7 @@ import com.owncloud.android.lib.common.OwnCloudClientFactory; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.operations.OAuth2GetAccessToken; +import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation; import com.owncloud.android.lib.common.operations.RemoteOperation; @@ -75,7 +77,6 @@ import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation; import com.owncloud.android.ui.dialog.SamlWebViewDialog; import com.owncloud.android.ui.dialog.SslUntrustedCertDialog; import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener; -import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener; import com.owncloud.android.utils.Log_OC; import com.owncloud.android.lib.resources.status.OwnCloudVersion; @@ -86,7 +87,7 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion; * @author David A. Velasco */ public class AuthenticatorActivity extends AccountAuthenticatorActivity - implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeListener, OnEditorActionListener, + implements OnRemoteOperationListener, OnFocusChangeListener, OnEditorActionListener, SsoWebViewClientListener, OnSslUntrustedCertListener { private static final String TAG = AuthenticatorActivity.class.getSimpleName(); @@ -1530,26 +1531,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity } /** - * Called from SslValidatorDialog when a new server certificate was correctly saved. - */ - public void onSavedCertificate() { - checkOcServer(); - reloadWebView(); - - } - - /** - * Called from SslValidatorDialog when a new server certificate could not be saved - * when the user requested it. - */ - @Override - public void onFailedSavingCertificate() { - showDialog(DIALOG_CERT_NOT_SAVED); - cancelWebView(); - } - - - /** * Called when the 'action' button in an IME is pressed ('enter' in software keyboard). * * Used to trigger the authentication check when the user presses 'enter' after writing the password, @@ -1665,40 +1646,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity } - - public void cancelWebView() { - Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG); - if (fd != null && fd instanceof SherlockDialogFragment) { - Dialog d = ((SherlockDialogFragment)fd).getDialog(); - if (d != null && d.isShowing()) { - d.dismiss(); - } - } - - } - - public void reloadWebView() { - Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG); - if (fd != null && fd instanceof SamlWebViewDialog) { - ((SamlWebViewDialog) fd).reloadWebView(); - } - } - - @Override - public void onCancelCertificate() { - cancelWebView(); - } - /** * Show untrusted cert dialog */ - public void showUntrustedCertDialog(X509Certificate x509Certificate, SslError error) { + public void showUntrustedCertDialog(X509Certificate x509Certificate, SslError error, SslErrorHandler handler) { // Show a dialog with the certificate info - SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstance(x509Certificate, error); + SslUntrustedCertDialog dialog = null; + if (x509Certificate == null) { + dialog = SslUntrustedCertDialog.newInstanceForEmptySslError(error, handler); + } else { + dialog = SslUntrustedCertDialog.newInstanceForFullSslError(x509Certificate, error, handler); + } FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); dialog.show(ft, DIALOG_UNTRUSTED_CERT); - } /** @@ -1706,7 +1667,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity */ public void showUntrustedCertDialog(RemoteOperationResult result) { // Show a dialog with the certificate info - SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstance(result, this); + SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError((CertificateCombinedException)result.getException()); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); dialog.show(ft, DIALOG_UNTRUSTED_CERT); @@ -1717,11 +1678,57 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity * Dismiss untrusted cert dialog */ public void dismissUntrustedCertDialog(){ - Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_UNTRUSTED_CERT); + /*Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_UNTRUSTED_CERT); if (frag != null) { - SslUntrustedCertDialog dialog = (SslUntrustedCertDialog) frag; + SslErrorViewAdapter dialog = (SslErrorViewAdapter) frag; dialog.dismiss(); } + */ + } + + /** + * Called from SslValidatorDialog when a new server certificate was correctly saved. + */ + public void onSavedCertificate() { + Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG); + if (fd == null) { + // if SAML dialog is not shown, the SslDialog was shown due to an SSL error in the server check + checkOcServer(); + } + } + + /** + * Called from SslValidatorDialog when a new server certificate could not be saved + * when the user requested it. + */ + @Override + public void onFailedSavingCertificate() { + showDialog(DIALOG_CERT_NOT_SAVED); + cancelWebView(); + } + + @Override + public void onCancelCertificate() { + cancelWebView(); } + + public void cancelWebView() { + Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG); + if (fd != null && fd instanceof SherlockDialogFragment) { + Dialog d = ((SherlockDialogFragment)fd).getDialog(); + if (d != null && d.isShowing()) { + d.dismiss(); + } + } + + } + + public void reloadWebView() { + Fragment fd = getSupportFragmentManager().findFragmentByTag(TAG_SAML_DIALOG); + if (fd != null && fd instanceof SamlWebViewDialog) { + ((SamlWebViewDialog) fd).reloadWebView(); + } + } + } diff --git a/src/com/owncloud/android/authentication/SsoWebViewClient.java b/src/com/owncloud/android/authentication/SsoWebViewClient.java index 89f66ef2..27e1f5b8 100644 --- a/src/com/owncloud/android/authentication/SsoWebViewClient.java +++ b/src/com/owncloud/android/authentication/SsoWebViewClient.java @@ -25,8 +25,6 @@ import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import com.owncloud.android.lib.common.network.NetworkUtils; -import com.actionbarsherlock.app.SherlockFragmentActivity; -import com.owncloud.android.ui.dialog.SslUntrustedCertDialogABSTRACT; import com.owncloud.android.utils.Log_OC; import android.content.Context; @@ -36,8 +34,6 @@ import android.net.http.SslError; import android.os.Bundle; import android.os.Handler; import android.os.Message; -import android.support.v4.app.FragmentManager; -import android.support.v4.app.FragmentTransaction; import android.view.KeyEvent; import android.view.View; import android.webkit.CookieManager; @@ -168,17 +164,8 @@ public class SsoWebViewClient extends WebViewClient { if (isKnownServer) { handler.proceed(); - } else if (x509Certificate != null) { - // Show a dialog with the certificate info - ((AuthenticatorActivity)mContext).showUntrustedCertDialog(x509Certificate, error); - handler.cancel(); } else { - // Show a dialog with the certificate information available in SslError (not full) - SslUntrustedCertDialogABSTRACT dialog = SslUntrustedCertDialogABSTRACT.newInstanceForEmptySslError(error, handler); - FragmentManager fm = ((SherlockFragmentActivity)mContext).getSupportFragmentManager(); - FragmentTransaction ft = fm.beginTransaction(); - dialog.show(ft, AuthenticatorActivity.DIALOG_UNTRUSTED_CERT); - // let's forward the handler, and see what happens... + ((AuthenticatorActivity)mContext).showUntrustedCertDialog(x509Certificate, error, handler); } } diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java index e246c4fd..4593e3f0 100644 --- a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -67,6 +67,7 @@ import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.operations.CreateFolderOperation; +import com.owncloud.android.lib.common.network.CertificateCombinedException; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; @@ -78,6 +79,7 @@ import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UnshareLinkOperation; import com.owncloud.android.services.OperationsService; import com.owncloud.android.syncadapter.FileSyncAdapter; +import com.owncloud.android.ui.adapter.SslErrorViewAdapter; import com.owncloud.android.ui.dialog.EditNameDialog; import com.owncloud.android.ui.dialog.SslUntrustedCertDialog; import com.owncloud.android.ui.dialog.EditNameDialog.EditNameDialogListener; @@ -1312,6 +1314,10 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa showDialog(DIALOG_CERT_NOT_SAVED); } + @Override + public void onCancelCertificate() { + // nothing to do + } /** * Updates the view associated to the activity after the finish of some operation over files @@ -1607,31 +1613,13 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa */ public void showUntrustedCertDialog(RemoteOperationResult result) { // Show a dialog with the certificate info - SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstance(result, this); + SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError((CertificateCombinedException)result.getException()); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); dialog.show(ft, DIALOG_UNTRUSTED_CERT); - } /** - * Dismiss untrusted cert dialog - */ - public void dismissUntrustedCertDialog(){ - Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_UNTRUSTED_CERT); - if (frag != null) { - SslUntrustedCertDialog dialog = (SslUntrustedCertDialog) frag; - dialog.dismiss(); - } - } - - @Override - public void onCancelCertificate() { - // TODO Auto-generated method stub - - } - - /** * Requests the download of the received {@link OCFile} , updates the UI * to monitor the download progress and prepares the activity to send the file * when the download finishes. diff --git a/src/com/owncloud/android/ui/adapter/CertificateCombinedExceptionViewAdapter.java b/src/com/owncloud/android/ui/adapter/CertificateCombinedExceptionViewAdapter.java new file mode 100644 index 00000000..54fa8aaf --- /dev/null +++ b/src/com/owncloud/android/ui/adapter/CertificateCombinedExceptionViewAdapter.java @@ -0,0 +1,75 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.owncloud.android.ui.adapter; + +import com.owncloud.android.R; +import com.owncloud.android.lib.common.network.CertificateCombinedException; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.ErrorViewAdapter; + +import android.view.View; +import android.widget.TextView; + +/** + * TODO + * + * @author masensio + * @author David A. Velasco + * + */ +public class CertificateCombinedExceptionViewAdapter implements SslUntrustedCertDialog.ErrorViewAdapter { + + //private final static String TAG = CertificateCombinedExceptionViewAdapter.class.getSimpleName(); + + private CertificateCombinedException mSslException = null; + + public CertificateCombinedExceptionViewAdapter(CertificateCombinedException sslException) { + mSslException = sslException; + } + + @Override + public void updateErrorView(View dialogView) { + /// clean + dialogView.findViewById(R.id.reason_no_info_about_error).setVisibility(View.GONE); + + /// refresh + if (mSslException.getCertPathValidatorException() != null) { + ((TextView)dialogView.findViewById(R.id.reason_cert_not_trusted)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_cert_not_trusted).setVisibility(View.GONE); + } + + if (mSslException.getCertificateExpiredException() != null) { + ((TextView)dialogView.findViewById(R.id.reason_cert_expired)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_cert_expired).setVisibility(View.GONE); + } + + if (mSslException.getCertificateNotYetValidException() != null) { + ((TextView)dialogView.findViewById(R.id.reason_cert_not_yet_valid)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_cert_not_yet_valid).setVisibility(View.GONE); + } + + if (mSslException.getSslPeerUnverifiedException() != null) { + ((TextView)dialogView.findViewById(R.id.reason_hostname_not_verified)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_hostname_not_verified).setVisibility(View.GONE); + } + + } +} diff --git a/src/com/owncloud/android/ui/adapter/SslCertificateViewAdapter.java b/src/com/owncloud/android/ui/adapter/SslCertificateViewAdapter.java new file mode 100644 index 00000000..f470a60c --- /dev/null +++ b/src/com/owncloud/android/ui/adapter/SslCertificateViewAdapter.java @@ -0,0 +1,128 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.owncloud.android.ui.adapter; + +import java.text.DateFormat; +import java.util.Date; + +import com.owncloud.android.R; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.CertificateViewAdapter; + +import android.net.http.SslCertificate; +import android.view.View; +import android.widget.TextView; + +/** + * TODO + * + * @author masensio + * @author David A. Velasco + */ +public class SslCertificateViewAdapter implements SslUntrustedCertDialog.CertificateViewAdapter { + + //private final static String TAG = SslCertificateViewAdapter.class.getSimpleName(); + + private SslCertificate mCertificate; + + + /** + * Constructor + * + * @param + */ + public SslCertificateViewAdapter(SslCertificate certificate) { + mCertificate = certificate; + } + + @Override + public void updateCertificateView(View dialogView) { + TextView nullCerView = (TextView) dialogView.findViewById(R.id.null_cert); + if (mCertificate != null) { + nullCerView.setVisibility(View.GONE); + showSubject(mCertificate.getIssuedTo(), dialogView); + showIssuer(mCertificate.getIssuedBy(), dialogView); + showValidity(mCertificate.getValidNotBeforeDate(), mCertificate.getValidNotAfterDate(), dialogView); + hideSignature(dialogView); + + } else { + nullCerView.setVisibility(View.VISIBLE); + } + } + + private void showValidity(Date notBefore, Date notAfter, View dialogView) { + TextView fromView = ((TextView)dialogView.findViewById(R.id.value_validity_from)); + TextView toView = ((TextView)dialogView.findViewById(R.id.value_validity_to)); + DateFormat dateFormat = DateFormat.getDateInstance(); + fromView.setText(dateFormat.format(notBefore)); + toView.setText(dateFormat.format(notAfter)); + } + + + private void showSubject(SslCertificate.DName subject, View dialogView) { + TextView cnView = ((TextView)dialogView.findViewById(R.id.value_subject_CN)); + cnView.setText(subject.getCName()); + cnView.setVisibility(View.VISIBLE); + + TextView oView = ((TextView)dialogView.findViewById(R.id.value_subject_O)); + oView.setText(subject.getOName()); + oView.setVisibility(View.VISIBLE); + + TextView ouView = ((TextView)dialogView.findViewById(R.id.value_subject_OU)); + ouView.setText(subject.getUName()); + ouView.setVisibility(View.VISIBLE); + + // SslCertificates don't offer this information + ((TextView)dialogView.findViewById(R.id.value_subject_C)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.value_subject_ST)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.value_subject_L)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.label_subject_C)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.label_subject_ST)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.label_subject_L)).setVisibility(View.GONE); + } + + + private void showIssuer(SslCertificate.DName issuer, View dialogView) { + TextView cnView = ((TextView)dialogView.findViewById(R.id.value_issuer_CN)); + cnView.setText(issuer.getCName()); + cnView.setVisibility(View.VISIBLE); + + TextView oView = ((TextView)dialogView.findViewById(R.id.value_issuer_O)); + oView.setText(issuer.getOName()); + oView.setVisibility(View.VISIBLE); + + TextView ouView = ((TextView)dialogView.findViewById(R.id.value_issuer_OU)); + ouView.setText(issuer.getUName()); + ouView.setVisibility(View.VISIBLE); + + // SslCertificates don't offer this information + ((TextView)dialogView.findViewById(R.id.value_issuer_C)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.value_issuer_ST)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.value_issuer_L)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.label_issuer_C)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.label_issuer_ST)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.label_issuer_L)).setVisibility(View.GONE); + } + + private void hideSignature(View dialogView) { + ((TextView)dialogView.findViewById(R.id.label_signature)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.label_signature_algorithm)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.value_signature_algorithm)).setVisibility(View.GONE); + ((TextView)dialogView.findViewById(R.id.value_signature)).setVisibility(View.GONE); + } + +} diff --git a/src/com/owncloud/android/ui/adapter/SslErrorViewAdapter.java b/src/com/owncloud/android/ui/adapter/SslErrorViewAdapter.java new file mode 100644 index 00000000..f0d5b2c8 --- /dev/null +++ b/src/com/owncloud/android/ui/adapter/SslErrorViewAdapter.java @@ -0,0 +1,75 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.owncloud.android.ui.adapter; + +import com.owncloud.android.R; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.ErrorViewAdapter; + +import android.net.http.SslError; +import android.view.View; +import android.widget.TextView; + +/** + * Dialog to show an Untrusted Certificate + * + * @author masensio + * @author David A. Velasco + * + */ +public class SslErrorViewAdapter implements SslUntrustedCertDialog.ErrorViewAdapter { + + //private final static String TAG = SslErrorViewAdapter.class.getSimpleName(); + + private SslError mSslError; + + public SslErrorViewAdapter(SslError sslError) { + mSslError = sslError; + } + + @Override + public void updateErrorView(View dialogView) { + /// clean + dialogView.findViewById(R.id.reason_no_info_about_error).setVisibility(View.GONE); + + /// refresh + if (mSslError.hasError(SslError.SSL_UNTRUSTED)) { + ((TextView)dialogView.findViewById(R.id.reason_cert_not_trusted)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_cert_not_trusted).setVisibility(View.GONE); + } + + if (mSslError.hasError(SslError.SSL_EXPIRED)) { + ((TextView)dialogView.findViewById(R.id.reason_cert_expired)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_cert_expired).setVisibility(View.GONE); + } + + if (mSslError.getPrimaryError() == SslError.SSL_NOTYETVALID) { + ((TextView)dialogView.findViewById(R.id.reason_cert_not_yet_valid)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_cert_not_yet_valid).setVisibility(View.GONE); + } + + if (mSslError.getPrimaryError() == SslError.SSL_IDMISMATCH) { + ((TextView)dialogView.findViewById(R.id.reason_hostname_not_verified)).setVisibility(View.VISIBLE); + } else { + dialogView.findViewById(R.id.reason_hostname_not_verified).setVisibility(View.GONE); + } + } + +} diff --git a/src/com/owncloud/android/ui/adapter/X509CertificateViewAdapter.java b/src/com/owncloud/android/ui/adapter/X509CertificateViewAdapter.java new file mode 100644 index 00000000..522f02f1 --- /dev/null +++ b/src/com/owncloud/android/ui/adapter/X509CertificateViewAdapter.java @@ -0,0 +1,205 @@ +/* ownCloud Android client application + * Copyright (C) 2012-2014 ownCloud Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.owncloud.android.ui.adapter; + +import java.security.cert.X509Certificate; +import java.text.DateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.security.auth.x500.X500Principal; + +import com.owncloud.android.R; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog; +import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.CertificateViewAdapter; + +import android.view.View; +import android.widget.TextView; + +/** + * + * @author masensio + * @author David A. Velasco + * + */ +public class X509CertificateViewAdapter implements SslUntrustedCertDialog.CertificateViewAdapter { + + //private final static String TAG = X509CertificateViewAdapter.class.getSimpleName(); + + private X509Certificate mCertificate = null; + + public X509CertificateViewAdapter(X509Certificate certificate) { + mCertificate = certificate; + } + + @Override + public void updateCertificateView(View dialogView) { + TextView nullCerView = (TextView) dialogView.findViewById(R.id.null_cert); + + if (mCertificate != null) { + nullCerView.setVisibility(View.GONE); + showSubject(mCertificate.getSubjectX500Principal(), dialogView); + showIssuer(mCertificate.getIssuerX500Principal(), dialogView); + showValidity(mCertificate.getNotBefore(), mCertificate.getNotAfter(), dialogView); + showSignature(dialogView); + + } else { + nullCerView.setVisibility(View.VISIBLE); + } + } + + private void showSignature(View dialogView) { + TextView sigView = ((TextView)dialogView.findViewById(R.id.value_signature)); + TextView algorithmView = ((TextView)dialogView.findViewById(R.id.value_signature_algorithm)); + sigView.setText(getHex(mCertificate.getSignature())); + algorithmView.setText(mCertificate.getSigAlgName()); + } + + public String getHex(final byte [] raw) { + if (raw == null) { + return null; + } + final StringBuilder hex = new StringBuilder(2 * raw.length); + for (final byte b : raw) { + final int hiVal = (b & 0xF0) >> 4; + final int loVal = b & 0x0F; + hex.append((char) ('0' + (hiVal + (hiVal / 10 * 7)))); + hex.append((char) ('0' + (loVal + (loVal / 10 * 7)))); + } + return hex.toString(); + } + + private void showValidity(Date notBefore, Date notAfter, View dialogView) { + TextView fromView = ((TextView)dialogView.findViewById(R.id.value_validity_from)); + TextView toView = ((TextView)dialogView.findViewById(R.id.value_validity_to)); + DateFormat dateFormat = DateFormat.getDateInstance(); + fromView.setText(dateFormat.format(notBefore)); + toView.setText(dateFormat.format(notAfter)); + } + + private void showSubject(X500Principal subject, View dialogView) { + Map s = parsePrincipal(subject); + TextView cnView = ((TextView)dialogView.findViewById(R.id.value_subject_CN)); + TextView oView = ((TextView)dialogView.findViewById(R.id.value_subject_O)); + TextView ouView = ((TextView)dialogView.findViewById(R.id.value_subject_OU)); + TextView cView = ((TextView)dialogView.findViewById(R.id.value_subject_C)); + TextView stView = ((TextView)dialogView.findViewById(R.id.value_subject_ST)); + TextView lView = ((TextView)dialogView.findViewById(R.id.value_subject_L)); + + if (s.get("CN") != null) { + cnView.setText(s.get("CN")); + cnView.setVisibility(View.VISIBLE); + } else { + cnView.setVisibility(View.GONE); + } + if (s.get("O") != null) { + oView.setText(s.get("O")); + oView.setVisibility(View.VISIBLE); + } else { + oView.setVisibility(View.GONE); + } + if (s.get("OU") != null) { + ouView.setText(s.get("OU")); + ouView.setVisibility(View.VISIBLE); + } else { + ouView.setVisibility(View.GONE); + } + if (s.get("C") != null) { + cView.setText(s.get("C")); + cView.setVisibility(View.VISIBLE); + } else { + cView.setVisibility(View.GONE); + } + if (s.get("ST") != null) { + stView.setText(s.get("ST")); + stView.setVisibility(View.VISIBLE); + } else { + stView.setVisibility(View.GONE); + } + if (s.get("L") != null) { + lView.setText(s.get("L")); + lView.setVisibility(View.VISIBLE); + } else { + lView.setVisibility(View.GONE); + } + } + + private void showIssuer(X500Principal issuer, View dialogView) { + Map s = parsePrincipal(issuer); + TextView cnView = ((TextView)dialogView.findViewById(R.id.value_issuer_CN)); + TextView oView = ((TextView)dialogView.findViewById(R.id.value_issuer_O)); + TextView ouView = ((TextView)dialogView.findViewById(R.id.value_issuer_OU)); + TextView cView = ((TextView)dialogView.findViewById(R.id.value_issuer_C)); + TextView stView = ((TextView)dialogView.findViewById(R.id.value_issuer_ST)); + TextView lView = ((TextView)dialogView.findViewById(R.id.value_issuer_L)); + + if (s.get("CN") != null) { + cnView.setText(s.get("CN")); + cnView.setVisibility(View.VISIBLE); + } else { + cnView.setVisibility(View.GONE); + } + if (s.get("O") != null) { + oView.setText(s.get("O")); + oView.setVisibility(View.VISIBLE); + } else { + oView.setVisibility(View.GONE); + } + if (s.get("OU") != null) { + ouView.setText(s.get("OU")); + ouView.setVisibility(View.VISIBLE); + } else { + ouView.setVisibility(View.GONE); + } + if (s.get("C") != null) { + cView.setText(s.get("C")); + cView.setVisibility(View.VISIBLE); + } else { + cView.setVisibility(View.GONE); + } + if (s.get("ST") != null) { + stView.setText(s.get("ST")); + stView.setVisibility(View.VISIBLE); + } else { + stView.setVisibility(View.GONE); + } + if (s.get("L") != null) { + lView.setText(s.get("L")); + lView.setVisibility(View.VISIBLE); + } else { + lView.setVisibility(View.GONE); + } + } + + + private Map parsePrincipal(X500Principal principal) { + Map result = new HashMap(); + String toParse = principal.getName(); + String[] pieces = toParse.split(","); + String[] tokens = {"CN", "O", "OU", "C", "ST", "L"}; + for (int i=0; i < pieces.length ; i++) { + for (int j=0; j> 4; - final int loVal = b & 0x0F; - hex.append((char) ('0' + (hiVal + (hiVal / 10 * 7)))); - hex.append((char) ('0' + (loVal + (loVal / 10 * 7)))); - } - return hex.toString(); - } + private class OnCertificateTrusted implements OnClickListener { - @SuppressWarnings("deprecation") - private void showValidity(Date notBefore, Date notAfter) { - TextView fromView = ((TextView)mView.findViewById(R.id.value_validity_from)); - TextView toView = ((TextView)mView.findViewById(R.id.value_validity_to)); - fromView.setText(notBefore.toLocaleString()); - toView.setText(notAfter.toLocaleString()); - } - - private void showSubject(X500Principal subject) { - Map s = parsePrincipal(subject); - TextView cnView = ((TextView)mView.findViewById(R.id.value_subject_CN)); - TextView oView = ((TextView)mView.findViewById(R.id.value_subject_O)); - TextView ouView = ((TextView)mView.findViewById(R.id.value_subject_OU)); - TextView cView = ((TextView)mView.findViewById(R.id.value_subject_C)); - TextView stView = ((TextView)mView.findViewById(R.id.value_subject_ST)); - TextView lView = ((TextView)mView.findViewById(R.id.value_subject_L)); - - if (s.get("CN") != null) { - cnView.setText(s.get("CN")); - cnView.setVisibility(View.VISIBLE); - } else { - cnView.setVisibility(View.GONE); - } - if (s.get("O") != null) { - oView.setText(s.get("O")); - oView.setVisibility(View.VISIBLE); - } else { - oView.setVisibility(View.GONE); - } - if (s.get("OU") != null) { - ouView.setText(s.get("OU")); - ouView.setVisibility(View.VISIBLE); - } else { - ouView.setVisibility(View.GONE); - } - if (s.get("C") != null) { - cView.setText(s.get("C")); - cView.setVisibility(View.VISIBLE); - } else { - cView.setVisibility(View.GONE); - } - if (s.get("ST") != null) { - stView.setText(s.get("ST")); - stView.setVisibility(View.VISIBLE); - } else { - stView.setVisibility(View.GONE); - } - if (s.get("L") != null) { - lView.setText(s.get("L")); - lView.setVisibility(View.VISIBLE); - } else { - lView.setVisibility(View.GONE); - } - } - - private void showIssuer(X500Principal issuer) { - Map s = parsePrincipal(issuer); - TextView cnView = ((TextView)mView.findViewById(R.id.value_issuer_CN)); - TextView oView = ((TextView)mView.findViewById(R.id.value_issuer_O)); - TextView ouView = ((TextView)mView.findViewById(R.id.value_issuer_OU)); - TextView cView = ((TextView)mView.findViewById(R.id.value_issuer_C)); - TextView stView = ((TextView)mView.findViewById(R.id.value_issuer_ST)); - TextView lView = ((TextView)mView.findViewById(R.id.value_issuer_L)); - - if (s.get("CN") != null) { - cnView.setText(s.get("CN")); - cnView.setVisibility(View.VISIBLE); - } else { - cnView.setVisibility(View.GONE); - } - if (s.get("O") != null) { - oView.setText(s.get("O")); - oView.setVisibility(View.VISIBLE); - } else { - oView.setVisibility(View.GONE); - } - if (s.get("OU") != null) { - ouView.setText(s.get("OU")); - ouView.setVisibility(View.VISIBLE); - } else { - ouView.setVisibility(View.GONE); - } - if (s.get("C") != null) { - cView.setText(s.get("C")); - cView.setVisibility(View.VISIBLE); - } else { - cView.setVisibility(View.GONE); - } - if (s.get("ST") != null) { - stView.setText(s.get("ST")); - stView.setVisibility(View.VISIBLE); - } else { - stView.setVisibility(View.GONE); - } - if (s.get("L") != null) { - lView.setText(s.get("L")); - lView.setVisibility(View.VISIBLE); - } else { - lView.setVisibility(View.GONE); - } - } + @Override + public void onClick(View v) { + dismiss(); + if (mHandler != null) { + mHandler.proceed(); + } + if (m509Certificate != null) { + Activity activity = getSherlockActivity(); + try { + NetworkUtils.addCertToKnownServersStore(m509Certificate, activity); // TODO make this asynchronously, it can take some time + ((OnSslUntrustedCertListener)activity).onSavedCertificate(); - - private Map parsePrincipal(X500Principal principal) { - Map result = new HashMap(); - String toParse = principal.getName(); - String[] pieces = toParse.split(","); - String[] tokens = {"CN", "O", "OU", "C", "ST", "L"}; - for (int i=0; i < pieces.length ; i++) { - for (int j=0; j. - * - */ -package com.owncloud.android.ui.dialog; - -import android.net.http.SslError; -import android.webkit.SslErrorHandler; - -import com.actionbarsherlock.app.SherlockDialogFragment; - -/** - * Dialog to show information about an untrusted certificate and allow the user - * to decide trust on it or not. - * - * Abstract implementation of common functionality for different dialogs that - * get the information about the error and the certificate from different classes. - * - * @author masensio - * @author David A. Velasco - */ -public abstract class SslUntrustedCertDialogABSTRACT extends SherlockDialogFragment { - - //private final static String TAG = SslUntrustedCertDialogABSTRACT.class.getSimpleName(); - - public static SslUntrustedCertDialogABSTRACT newInstanceForEmptySslError(SslError error, SslErrorHandler handler) { - if (error == null) { - throw new IllegalArgumentException("Trying to create instance with a parameter error == null"); - } - return SslUntrustedCertDialogForEmptySslError.newInstance(error, handler); - } - - // TODO - complete when merged - /* - public static SslUntrustedCertDialogABSTRACT newInstanceForFullSslError(X509Certificate cert, SslError error, OnSslUntrustedCertListener listener, SslErrorHandler handler) { - if (cert == null) { - throw new IllegalArgumentException("Trying to create instance with a parameter error == null"); - } - if (error == null) { - throw new IllegalArgumentException("Trying to create instance with a parameter error == null"); - } - return new SslUntrustedCertDialog(cert, listener, handler); - } - */ - - - public interface OnSslUntrustedCertListener { - public void onSavedCertificate(); - public void onFailedSavingCertificate(); - } - -} diff --git a/src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogForEmptySslError.java b/src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogForEmptySslError.java deleted file mode 100644 index d9173bb0..00000000 --- a/src/com/owncloud/android/ui/dialog/SslUntrustedCertDialogForEmptySslError.java +++ /dev/null @@ -1,263 +0,0 @@ -/* ownCloud Android client application - * Copyright (C) 2012-2014 ownCloud Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package com.owncloud.android.ui.dialog; - -import java.text.DateFormat; -import java.util.Date; - -import com.owncloud.android.R; -import com.owncloud.android.authentication.AuthenticatorActivity; - -import android.app.Activity; -import android.app.Dialog; -import android.net.http.SslCertificate; -import android.net.http.SslError; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.view.Window; -import android.webkit.SslErrorHandler; -import android.webkit.WebView; -import android.widget.Button; -import android.widget.TextView; - -/** - * Dialog to show an Untrusted Certificate - * - * @author masensio - * @author David A. Velasco - */ -public class SslUntrustedCertDialogForEmptySslError extends SslUntrustedCertDialogABSTRACT { - - //private final static String TAG = SslUntrustedCertDialogForEmptySslError.class.getSimpleName(); - - private SslError mError; - private SslErrorHandler mHandler; - private View mView; - - - /** - * Factory method. - * - * @param error Error occurred; details about it will be shown in the dialog. - * @param handler Handler to indicate to the {@link WebView} where the error was found what to do next. - * @return New dialog. - */ - public static SslUntrustedCertDialogForEmptySslError newInstance(SslError error, SslErrorHandler handler) { - return new SslUntrustedCertDialogForEmptySslError(error, handler); - } - - - /** - * Empty constructor. - * - * Required by Android framework. Never used, since the state is retained; see {@link #onCreate(Bundle)} - */ - public SslUntrustedCertDialogForEmptySslError() {} - - - /** - * Private constructor. - * - * Used by the factory method {@link #newInstance(SslError, SslErrorHandler)}. - * - * @param error Error occurred; details about it will be shown in the dialog. - * @param handler Handler to indicate to the {@link WebView} where the error was found what to do next. - */ - private SslUntrustedCertDialogForEmptySslError(SslError error, SslErrorHandler handler) { - mError = error; - mHandler = handler; - } - - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - /*if (!(activity instanceof OnSslUntrustedCertListener)) { - throw new IllegalArgumentException("Trying to attach to an Activity not implementing " + OnSslUntrustedCertListener.class.getCanonicalName()); - }*/ - } - - - // TODO try to move to the parent class ? - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setRetainInstance(true); // force to keep the state of the fragment on configuration changes (such as device rotations) - setCancelable(false); - mView = null; - } - - // try to move to the parent class ? - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - // Create a view by inflating desired layout - if (mView == null) { - mView = inflater.inflate(R.layout.ssl_untrusted_cert_layout, container, false); - } else { - ((ViewGroup)mView.getParent()).removeView(mView); - } - - showNoMessageError(); - - Button ok = (Button) mView.findViewById(R.id.ok); - ok.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - //AuthenticatorActivity act = ((AuthenticatorActivity)getSherlockActivity()); - mHandler.proceed(); - dismiss(); - } - }); - - Button cancel = (Button) mView.findViewById(R.id.cancel); - cancel.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - AuthenticatorActivity act = ((AuthenticatorActivity)getSherlockActivity()); - getDialog().cancel(); - mHandler.cancel(); - act.cancelWebView(); - } - }); - - Button details = (Button) mView.findViewById(R.id.details_btn); - details.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - View detailsScroll = mView.findViewById(R.id.details_scroll); - if (detailsScroll.getVisibility() == View.VISIBLE) { - detailsScroll.setVisibility(View.GONE); - ((Button) v).setText(R.string.ssl_validator_btn_details_see); - - } else { - detailsScroll.setVisibility(View.VISIBLE); - ((Button) v).setText(R.string.ssl_validator_btn_details_hide); - showCertificateData(); - } - } - }); - - return mView; - } - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final Dialog dialog = super.onCreateDialog(savedInstanceState); - dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - return dialog; - } - - @Override - public void onDestroyView() { - if (getDialog() != null && getRetainInstance()) - getDialog().setDismissMessage(null); - super.onDestroyView(); - } - - private void showCertificateData() { - TextView nullCerView = (TextView) mView.findViewById(R.id.null_cert); - SslCertificate cert = mError.getCertificate(); - if (cert != null) { - nullCerView.setVisibility(View.GONE); - showSubject(cert.getIssuedTo()); - showIssuer(cert.getIssuedBy()); - showValidity(cert.getValidNotBeforeDate(), cert.getValidNotAfterDate()); - hideSignature(); - - } else { - nullCerView.setVisibility(View.VISIBLE); - } - } - - private void showValidity(Date notBefore, Date notAfter) { - TextView fromView = ((TextView)mView.findViewById(R.id.value_validity_from)); - TextView toView = ((TextView)mView.findViewById(R.id.value_validity_to)); - DateFormat dateFormat = DateFormat.getDateInstance(); - fromView.setText(dateFormat.format(notBefore)); - toView.setText(dateFormat.format(notAfter)); - } - - - private void showSubject(SslCertificate.DName subject) { - TextView cnView = ((TextView)mView.findViewById(R.id.value_subject_CN)); - cnView.setText(subject.getCName()); - cnView.setVisibility(View.VISIBLE); - - TextView oView = ((TextView)mView.findViewById(R.id.value_subject_O)); - oView.setText(subject.getOName()); - oView.setVisibility(View.VISIBLE); - - TextView ouView = ((TextView)mView.findViewById(R.id.value_subject_OU)); - ouView.setText(subject.getUName()); - ouView.setVisibility(View.VISIBLE); - - // SslCertificates don't offer this information - ((TextView)mView.findViewById(R.id.value_subject_C)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.value_subject_ST)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.value_subject_L)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.label_subject_C)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.label_subject_ST)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.label_subject_L)).setVisibility(View.GONE); - } - - - private void showIssuer(SslCertificate.DName issuer) { - TextView cnView = ((TextView)mView.findViewById(R.id.value_issuer_CN)); - cnView.setText(issuer.getCName()); - cnView.setVisibility(View.VISIBLE); - - TextView oView = ((TextView)mView.findViewById(R.id.value_issuer_O)); - oView.setText(issuer.getOName()); - oView.setVisibility(View.VISIBLE); - - TextView ouView = ((TextView)mView.findViewById(R.id.value_issuer_OU)); - ouView.setText(issuer.getUName()); - ouView.setVisibility(View.VISIBLE); - - // SslCertificates don't offer this information - ((TextView)mView.findViewById(R.id.value_issuer_C)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.value_issuer_ST)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.value_issuer_L)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.label_issuer_C)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.label_issuer_ST)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.label_issuer_L)).setVisibility(View.GONE); - } - - private void hideSignature() { - ((TextView)mView.findViewById(R.id.label_signature)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.label_signature_algorithm)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.value_signature_algorithm)).setVisibility(View.GONE); - ((TextView)mView.findViewById(R.id.value_signature)).setVisibility(View.GONE); - } - - private void showNoMessageError() { - /// clean - mView.findViewById(R.id.reason_cert_not_trusted).setVisibility(View.GONE); - mView.findViewById(R.id.reason_cert_expired).setVisibility(View.GONE); - mView.findViewById(R.id.reason_cert_not_yet_valid).setVisibility(View.GONE); - mView.findViewById(R.id.reason_hostname_not_verified).setVisibility(View.GONE); - mView.findViewById(R.id.details_scroll).setVisibility(View.GONE); - - mView.findViewById(R.id.reason_no_info_about_error).setVisibility(View.VISIBLE); - - } -}