1 /* ownCloud Android client application
4 * @author David A. Velasco
5 * Copyright (C) 2012-2014 ownCloud Inc.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2,
9 * as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 package com
.owncloud
.android
.ui
.dialog
;
22 import java
.io
.IOException
;
23 import java
.security
.GeneralSecurityException
;
24 import java
.security
.cert
.X509Certificate
;
26 import android
.app
.Activity
;
27 import android
.app
.Dialog
;
28 import android
.net
.http
.SslError
;
29 import android
.os
.Bundle
;
30 import android
.view
.LayoutInflater
;
31 import android
.view
.View
;
32 import android
.view
.ViewGroup
;
33 import android
.view
.Window
;
34 import android
.view
.View
.OnClickListener
;
35 import android
.webkit
.SslErrorHandler
;
36 import android
.widget
.Button
;
38 import com
.actionbarsherlock
.app
.SherlockDialogFragment
;
39 import com
.owncloud
.android
.R
;
40 import com
.owncloud
.android
.lib
.common
.network
.CertificateCombinedException
;
41 import com
.owncloud
.android
.lib
.common
.network
.NetworkUtils
;
42 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
;
43 import com
.owncloud
.android
.ui
.adapter
.CertificateCombinedExceptionViewAdapter
;
44 import com
.owncloud
.android
.ui
.adapter
.SslCertificateViewAdapter
;
45 import com
.owncloud
.android
.ui
.adapter
.SslErrorViewAdapter
;
46 import com
.owncloud
.android
.ui
.adapter
.X509CertificateViewAdapter
;
49 * Dialog to show information about an untrusted certificate and allow the user
50 * to decide trust on it or not.
52 * Abstract implementation of common functionality for different dialogs that
53 * get the information about the error and the certificate from different classes.
55 public class SslUntrustedCertDialog
extends SherlockDialogFragment
{
57 private final static String TAG
= SslUntrustedCertDialog
.class.getSimpleName();
59 protected View mView
= null
;
60 protected SslErrorHandler mHandler
= null
;
61 protected X509Certificate m509Certificate
= null
;
63 private ErrorViewAdapter mErrorViewAdapter
= null
;
64 private CertificateViewAdapter mCertificateViewAdapter
= null
;
66 public static SslUntrustedCertDialog
newInstanceForEmptySslError(SslError error
, SslErrorHandler handler
) {
68 throw new IllegalArgumentException("Trying to create instance with parameter error == null");
70 if (handler
== null
) {
71 throw new IllegalArgumentException("Trying to create instance with parameter handler == null");
73 SslUntrustedCertDialog dialog
= new SslUntrustedCertDialog();
74 dialog
.mHandler
= handler
;
75 dialog
.mErrorViewAdapter
= new SslErrorViewAdapter(error
);
76 dialog
.mCertificateViewAdapter
= new SslCertificateViewAdapter(error
.getCertificate());
80 public static SslUntrustedCertDialog
newInstanceForFullSslError(CertificateCombinedException sslException
) {
81 if (sslException
== null
) {
82 throw new IllegalArgumentException("Trying to create instance with parameter sslException == null");
84 SslUntrustedCertDialog dialog
= new SslUntrustedCertDialog();
85 dialog
.m509Certificate
= sslException
.getServerCertificate();
86 dialog
.mErrorViewAdapter
= new CertificateCombinedExceptionViewAdapter(sslException
);
87 dialog
.mCertificateViewAdapter
= new X509CertificateViewAdapter(sslException
.getServerCertificate());
91 public static SslUntrustedCertDialog
newInstanceForFullSslError(X509Certificate cert
, SslError error
, SslErrorHandler handler
) {
93 throw new IllegalArgumentException("Trying to create instance with parameter cert == null");
96 throw new IllegalArgumentException("Trying to create instance with parameter error == null");
98 if (handler
== null
) {
99 throw new IllegalArgumentException("Trying to create instance with parameter handler == null");
101 SslUntrustedCertDialog dialog
= new SslUntrustedCertDialog();
102 dialog
.m509Certificate
= cert
;
103 dialog
.mHandler
= handler
;
104 dialog
.mErrorViewAdapter
= new SslErrorViewAdapter(error
);
105 dialog
.mCertificateViewAdapter
= new X509CertificateViewAdapter(cert
);
111 public void onAttach(Activity activity
) {
112 Log_OC
.d(TAG
, "onAttach");
113 super.onAttach(activity
);
114 if (!(activity
instanceof OnSslUntrustedCertListener
)) {
115 throw new IllegalArgumentException("The host activity must implement " + OnSslUntrustedCertListener
.class.getCanonicalName());
121 public void onCreate(Bundle savedInstanceState
) {
122 Log_OC
.d(TAG
, "onCreate, savedInstanceState is " + savedInstanceState
);
123 super.onCreate(savedInstanceState
);
124 setRetainInstance(true
); // force to keep the state of the fragment on configuration changes (such as device rotations)
125 setCancelable(false
);
130 public View
onCreateView(LayoutInflater inflater
, ViewGroup container
, Bundle savedInstanceState
) {
131 Log_OC
.d(TAG
, "onCreateView, savedInsanceState is " + savedInstanceState
);
132 // Create a view by inflating desired layout
134 mView
= inflater
.inflate(R
.layout
.ssl_untrusted_cert_layout
, container
, false
);
135 mView
.findViewById(R
.id
.details_scroll
).setVisibility(View
.GONE
);
136 mErrorViewAdapter
.updateErrorView(mView
);
138 ((ViewGroup
)mView
.getParent()).removeView(mView
);
141 Button ok
= (Button
) mView
.findViewById(R
.id
.ok
);
142 ok
.setOnClickListener(new OnCertificateTrusted());
144 Button cancel
= (Button
) mView
.findViewById(R
.id
.cancel
);
145 cancel
.setOnClickListener(new OnCertificateNotTrusted());
147 Button details
= (Button
) mView
.findViewById(R
.id
.details_btn
);
148 details
.setOnClickListener(new OnClickListener() {
151 public void onClick(View v
) {
152 View detailsScroll
= mView
.findViewById(R
.id
.details_scroll
);
153 if (detailsScroll
.getVisibility() == View
.VISIBLE
) {
154 detailsScroll
.setVisibility(View
.GONE
);
155 ((Button
) v
).setText(R
.string
.ssl_validator_btn_details_see
);
158 detailsScroll
.setVisibility(View
.VISIBLE
);
159 ((Button
) v
).setText(R
.string
.ssl_validator_btn_details_hide
);
160 mCertificateViewAdapter
.updateCertificateView(mView
);
171 public Dialog
onCreateDialog(Bundle savedInstanceState
) {
172 Log_OC
.d(TAG
, "onCreateDialog, savedInstanceState is " + savedInstanceState
);
173 final Dialog dialog
= super.onCreateDialog(savedInstanceState
);
174 dialog
.requestWindowFeature(Window
.FEATURE_NO_TITLE
);
179 public void onDestroyView() {
180 Log_OC
.d(TAG
, "onDestroyView");
181 if (getDialog() != null
&& getRetainInstance())
182 getDialog().setDismissMessage(null
);
183 super.onDestroyView();
186 private class OnCertificateNotTrusted
implements OnClickListener
{
189 public void onClick(View v
) {
190 getDialog().cancel();
191 if (mHandler
!= null
) {
194 ((OnSslUntrustedCertListener
)getSherlockActivity()).onCancelCertificate();
199 private class OnCertificateTrusted
implements OnClickListener
{
202 public void onClick(View v
) {
204 if (mHandler
!= null
) {
207 if (m509Certificate
!= null
) {
208 Activity activity
= getSherlockActivity();
210 NetworkUtils
.addCertToKnownServersStore(m509Certificate
, activity
); // TODO make this asynchronously, it can take some time
211 ((OnSslUntrustedCertListener
)activity
).onSavedCertificate();
213 } catch (GeneralSecurityException e
) {
214 ((OnSslUntrustedCertListener
)activity
).onFailedSavingCertificate();
215 Log_OC
.e(TAG
, "Server certificate could not be saved in the known-servers trust store ", e
);
217 } catch (IOException e
) {
218 ((OnSslUntrustedCertListener
)activity
).onFailedSavingCertificate();
219 Log_OC
.e(TAG
, "Server certificate could not be saved in the known-servers trust store ", e
);
227 public interface OnSslUntrustedCertListener
{
228 public void onSavedCertificate();
229 public void onFailedSavingCertificate();
230 public void onCancelCertificate();
233 public interface ErrorViewAdapter
{
234 void updateErrorView(View mView
);
237 public interface CertificateViewAdapter
{
238 void updateCertificateView(View mView
);