mirror of
https://github.com/nextcloud/android.git
synced 2024-11-27 09:39:25 +03:00
OC-3116: Add a warning dialog for untrusted SslCertificates and show it instead of call proceed() directly
This commit is contained in:
parent
e280f5e618
commit
8e1a2573b9
7 changed files with 826 additions and 24 deletions
413
res/layout/ssl_untrusted_cert_layout.xml
Normal file
413
res/layout/ssl_untrusted_cert_layout.xml
Normal file
|
@ -0,0 +1,413 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
ownCloud Android client application
|
||||
|
||||
Copyright (C) 2012-2013 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 <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_header"
|
||||
android:padding="5dp"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_reason_cert_not_trusted"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:paddingLeft="20dp"
|
||||
android:text="@string/ssl_validator_reason_cert_not_trusted"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/untrusted_details_scroll"
|
||||
android:visibility="gone"
|
||||
android:padding="20dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="180dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/untrusted_details_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="left"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_null_cert"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:paddingLeft="20dp"
|
||||
android:text="@string/ssl_validator_null_cert"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_subject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text="@string/ssl_validator_label_subject"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_subject_CN"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_CN"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_subject_CN"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_subject_O"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_O"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_subject_O"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_subject_OU"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_OU"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_subject_OU"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_subject_ST"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_ST"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_subject_ST"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_subject_C"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_C"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_subject_C"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_subject_L"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_L"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_subject_L"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_issuer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text="@string/ssl_validator_label_issuer"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_issuer_CN"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_CN"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_issuer_CN"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_issuer_O"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_O"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_issuer_O"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_issuer_OU"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_OU"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_issuer_OU"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_issuer_ST"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_ST"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_issuer_ST"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_issuer_C"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_C"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_issuer_C"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_issuer_L"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_L"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_issuer_L"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_validity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text="@string/ssl_validator_label_validity"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_validity_from"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_validity_from"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_validity_from"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_validity_to"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_validity_to"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_validity_to"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_signature"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text="@string/ssl_validator_label_signature"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_label_signature_algorithm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssl_validator_label_signature_algorithm"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_signature_algorithm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_value_signature"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="5dp"
|
||||
android:text=""
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/untrusted_question"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
android:text="@string/ssl_validator_question"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
>
|
||||
</TextView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center" >
|
||||
|
||||
<Button
|
||||
android:id="@+id/untrusted_cancel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/common_cancel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/untrusted_details_btn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/ssl_validator_btn_details_see" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/untrusted_ok"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/common_ok" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -215,6 +215,7 @@
|
|||
<string name="ssl_validator_label_validity_to">To:</string>
|
||||
<string name="ssl_validator_label_signature">Signature:</string>
|
||||
<string name="ssl_validator_label_signature_algorithm">Algorithm:</string>
|
||||
<string name="ssl_validator_null_cert">The certificate could not be shown.</string>
|
||||
|
||||
<string name="placeholder_sentence">This is a placeholder</string>
|
||||
<string name="placeholder_filename">placeholder.txt</string>
|
||||
|
|
|
@ -1665,4 +1665,26 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
|
|||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,25 +18,30 @@
|
|||
package com.owncloud.android.authentication;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
|
||||
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;
|
||||
import com.owncloud.android.utils.Log_OC;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.http.SslCertificate;
|
||||
import android.net.http.SslError;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.webkit.CookieManager;
|
||||
|
@ -56,10 +61,12 @@ import android.webkit.WebViewClient;
|
|||
*
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
public class SsoWebViewClient extends WebViewClient {
|
||||
public class SsoWebViewClient extends WebViewClient implements OnSslUntrustedCertListener {
|
||||
|
||||
private static final String TAG = SsoWebViewClient.class.getSimpleName();
|
||||
|
||||
public final static String DIALOG_UNTRUSTED_CERT = "UNTRUSTED CERT";
|
||||
|
||||
public interface SsoWebViewClientListener {
|
||||
public void onSsoFinished(String sessionCookie);
|
||||
}
|
||||
|
@ -149,7 +156,7 @@ public class SsoWebViewClient extends WebViewClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) {
|
||||
public void onReceivedSslError (final WebView view, final SslErrorHandler handler, SslError error) {
|
||||
Log_OC.d(TAG, "onReceivedSslError : " + error);
|
||||
// Test 1
|
||||
X509Certificate x509Certificate = getX509CertificateFromError(error);
|
||||
|
@ -160,24 +167,20 @@ public class SsoWebViewClient extends WebViewClient {
|
|||
|
||||
try {
|
||||
isKnowServer = NetworkUtils.isCertInKnownServersStore((Certificate) x509Certificate, mContext);
|
||||
} catch (KeyStoreException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (CertificateException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (isKnowServer) {
|
||||
handler.proceed();
|
||||
} else {
|
||||
|
||||
// Show a dialog with the certificate info
|
||||
SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstance(mContext, x509Certificate, this, handler);
|
||||
FragmentManager fm = ((FragmentActivity)mContext).getSupportFragmentManager();
|
||||
FragmentTransaction ft = fm.beginTransaction();
|
||||
dialog.show(ft, DIALOG_UNTRUSTED_CERT);
|
||||
handler.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,11 +204,6 @@ public class SsoWebViewClient extends WebViewClient {
|
|||
x509Certificate = null;
|
||||
}
|
||||
}
|
||||
|
||||
// if (x509Certificate != null) {
|
||||
// Log_OC.d(TAG, "------>>>>> x509Certificate " + x509Certificate.toString());
|
||||
// }
|
||||
|
||||
return x509Certificate;
|
||||
}
|
||||
|
||||
|
@ -247,4 +245,19 @@ public class SsoWebViewClient extends WebViewClient {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailedSavingCertificate() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
builder.setMessage(mContext.getString(R.string.ssl_validator_not_saved));
|
||||
builder.setCancelable(false);
|
||||
builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
};
|
||||
});
|
||||
builder.create().show();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -281,4 +281,9 @@ public class SamlWebViewDialog extends SherlockDialogFragment {
|
|||
super.show(manager, tag);
|
||||
}
|
||||
|
||||
public void reloadWebView() {
|
||||
mSsoWebView.reload();
|
||||
}
|
||||
|
||||
|
||||
}
|
347
src/com/owncloud/android/ui/dialog/SslUntrustedCertDialog.java
Normal file
347
src/com/owncloud/android/ui/dialog/SslUntrustedCertDialog.java
Normal file
|
@ -0,0 +1,347 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.owncloud.android.ui.dialog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockDialogFragment;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
import com.owncloud.android.lib.common.network.NetworkUtils;
|
||||
import com.owncloud.android.utils.Log_OC;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
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.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* Dialog to show an Untrusted Certificate
|
||||
*
|
||||
* @author masensio
|
||||
*
|
||||
*/
|
||||
public class SslUntrustedCertDialog extends SherlockDialogFragment{
|
||||
|
||||
private final static String TAG = SslUntrustedCertDialog.class.getSimpleName();
|
||||
|
||||
private X509Certificate mCertificate;
|
||||
private View mView;
|
||||
private SslErrorHandler mHandler;
|
||||
|
||||
private OnSslUntrustedCertListener mListener;
|
||||
|
||||
public SslUntrustedCertDialog() {
|
||||
}
|
||||
|
||||
public SslUntrustedCertDialog(X509Certificate cert, OnSslUntrustedCertListener listener, SslErrorHandler handler) {
|
||||
mCertificate = cert;
|
||||
mListener = listener;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
public static SslUntrustedCertDialog newInstance(Context context, X509Certificate cert, OnSslUntrustedCertListener listener,
|
||||
SslErrorHandler handler) {
|
||||
if (cert != null){
|
||||
SslUntrustedCertDialog dialog = new SslUntrustedCertDialog(cert, listener, handler);
|
||||
return dialog;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
setCancelable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
// Create a view by inflating desired layout
|
||||
mView = inflater.inflate(R.layout.ssl_untrusted_cert_layout, container, false);
|
||||
|
||||
Button ok = (Button) mView.findViewById(R.id.untrusted_ok);
|
||||
ok.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
saveServerCert();
|
||||
dismiss();
|
||||
if (mListener != null) {
|
||||
((AuthenticatorActivity)getSherlockActivity()).reloadWebView();
|
||||
|
||||
}
|
||||
else
|
||||
Log_OC.d(TAG, "Nobody there to notify the certificate was saved");
|
||||
|
||||
} catch (GeneralSecurityException e) {
|
||||
dismiss();
|
||||
if (mListener != null) {
|
||||
((AuthenticatorActivity)getSherlockActivity()).cancelWebView();
|
||||
mListener.onFailedSavingCertificate();
|
||||
}
|
||||
Log_OC.e(TAG, "Server certificate could not be saved in the known servers trust store ", e);
|
||||
|
||||
} catch (IOException e) {
|
||||
dismiss();
|
||||
if (mListener != null) {
|
||||
((AuthenticatorActivity)getSherlockActivity()).cancelWebView();
|
||||
mListener.onFailedSavingCertificate();
|
||||
}
|
||||
Log_OC.e(TAG, "Server certificate could not be saved in the known servers trust store ", e);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Button cancel = (Button) mView.findViewById(R.id.untrusted_cancel);
|
||||
cancel.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getDialog().cancel();
|
||||
((AuthenticatorActivity)getSherlockActivity()).cancelWebView();
|
||||
}
|
||||
});
|
||||
|
||||
Button details = (Button) mView.findViewById(R.id.untrusted_details_btn);
|
||||
details.setOnClickListener(new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
View detailsScroll = mView.findViewById(R.id.untrusted_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(mCertificate);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
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(X509Certificate cert) {
|
||||
|
||||
TextView nullCerView = (TextView) mView.findViewById(R.id.untrusted_null_cert);
|
||||
|
||||
if (cert != null) {
|
||||
nullCerView.setVisibility(View.GONE);
|
||||
showSubject(cert.getSubjectX500Principal());
|
||||
showIssuer(cert.getIssuerX500Principal());
|
||||
showValidity(cert.getNotBefore(), cert.getNotAfter());
|
||||
showSignature(cert);
|
||||
|
||||
} else {
|
||||
nullCerView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private void showSignature(X509Certificate cert) {
|
||||
TextView sigView = ((TextView)mView.findViewById(R.id.untrusted_value_signature));
|
||||
TextView algorithmView = ((TextView)mView.findViewById(R.id.untrusted_value_signature_algorithm));
|
||||
sigView.setText(getHex(cert.getSignature()));
|
||||
algorithmView.setText(cert.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();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void showValidity(Date notBefore, Date notAfter) {
|
||||
TextView fromView = ((TextView)mView.findViewById(R.id.untrusted_value_validity_from));
|
||||
TextView toView = ((TextView)mView.findViewById(R.id.untrusted_value_validity_to));
|
||||
fromView.setText(notBefore.toLocaleString());
|
||||
toView.setText(notAfter.toLocaleString());
|
||||
}
|
||||
|
||||
private void showSubject(X500Principal subject) {
|
||||
Map<String, String> s = parsePrincipal(subject);
|
||||
TextView cnView = ((TextView)mView.findViewById(R.id.untrusted_value_subject_CN));
|
||||
TextView oView = ((TextView)mView.findViewById(R.id.untrusted_value_subject_O));
|
||||
TextView ouView = ((TextView)mView.findViewById(R.id.untrusted_value_subject_OU));
|
||||
TextView cView = ((TextView)mView.findViewById(R.id.untrusted_value_subject_C));
|
||||
TextView stView = ((TextView)mView.findViewById(R.id.untrusted_value_subject_ST));
|
||||
TextView lView = ((TextView)mView.findViewById(R.id.untrusted_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<String, String> s = parsePrincipal(issuer);
|
||||
TextView cnView = ((TextView)mView.findViewById(R.id.untrusted_value_issuer_CN));
|
||||
TextView oView = ((TextView)mView.findViewById(R.id.untrusted_value_issuer_O));
|
||||
TextView ouView = ((TextView)mView.findViewById(R.id.untrusted_value_issuer_OU));
|
||||
TextView cView = ((TextView)mView.findViewById(R.id.untrusted_value_issuer_C));
|
||||
TextView stView = ((TextView)mView.findViewById(R.id.untrusted_value_issuer_ST));
|
||||
TextView lView = ((TextView)mView.findViewById(R.id.untrusted_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<String, String> parsePrincipal(X500Principal principal) {
|
||||
Map<String, String> result = new HashMap<String, String>();
|
||||
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<tokens.length; j++) {
|
||||
if (pieces[i].startsWith(tokens[j] + "=")) {
|
||||
result.put(tokens[j], pieces[i].substring(tokens[j].length()+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void saveServerCert() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
|
||||
if (mCertificate != null) {
|
||||
// TODO make this asynchronously, it can take some time
|
||||
NetworkUtils.addCertToKnownServersStore(mCertificate, getSherlockActivity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface OnSslUntrustedCertListener {
|
||||
public void onFailedSavingCertificate();
|
||||
}
|
||||
|
||||
}
|
|
@ -223,6 +223,7 @@ public class SslValidatorDialog extends Dialog {
|
|||
return hex.toString();
|
||||
}
|
||||
|
||||
@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));
|
||||
|
|
Loading…
Reference in a new issue