diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-28 18:27:29 +0200 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-09-28 18:27:29 +0200 |
commit | 0e613aff2e617ca12c1b2e1032b21334c2ca674a (patch) | |
tree | 4e16d6a086cbe12875454fba520241ac84e277c7 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog | |
parent | b65a23f2d46f905160b47e044de12cf9177dfd51 (diff) | |
parent | 3df9bea4554c0edddce57aa6a2e32cfe5250ed72 (diff) | |
download | open-keychain-0e613aff2e617ca12c1b2e1032b21334c2ca674a.tar.gz open-keychain-0e613aff2e617ca12c1b2e1032b21334c2ca674a.tar.bz2 open-keychain-0e613aff2e617ca12c1b2e1032b21334c2ca674a.zip |
Merge remote-tracking branch 'origin/master' into encrypted-export
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog')
2 files changed, 65 insertions, 249 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java index 47bc7dfda..3d96f3c6d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/AddEditKeyserverDialogFragment.java @@ -24,6 +24,7 @@ import java.net.URI; import java.net.URISyntaxException; import android.app.Activity; +import android.support.design.widget.TextInputLayout; import android.support.v7.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; @@ -44,6 +45,7 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.EditText; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; @@ -54,6 +56,7 @@ import com.squareup.okhttp.Request; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.keyimport.HkpKeyserver; +import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.TlsHelper; @@ -68,11 +71,9 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On private static final String ARG_KEYSERVER = "arg_keyserver"; public static final int MESSAGE_OKAY = 1; - public static final int MESSAGE_VERIFICATION_FAILED = 2; public static final String MESSAGE_KEYSERVER = "new_keyserver"; public static final String MESSAGE_VERIFIED = "verified"; - public static final String MESSAGE_FAILURE_REASON = "failure_reason"; public static final String MESSAGE_KEYSERVER_DELETED = "keyserver_deleted"; public static final String MESSAGE_DIALOG_ACTION = "message_dialog_action"; public static final String MESSAGE_EDIT_POSITION = "keyserver_edited_position"; @@ -82,7 +83,9 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On private int mPosition; private EditText mKeyserverEditText; + private TextInputLayout mKeyserverEditTextLayout; private CheckBox mVerifyKeyserverCheckBox; + private CheckBox mOnlyTrustedKeyserverCheckBox; public enum DialogAction { ADD, @@ -91,7 +94,8 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On public enum FailureReason { INVALID_URL, - CONNECTION_FAILED + CONNECTION_FAILED, + NO_PINNED_CERTIFICATE } public static AddEditKeyserverDialogFragment newInstance(Messenger messenger, @@ -126,7 +130,15 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On alert.setView(view); mKeyserverEditText = (EditText) view.findViewById(R.id.keyserver_url_edit_text); - mVerifyKeyserverCheckBox = (CheckBox) view.findViewById(R.id.verify_keyserver_checkbox); + mKeyserverEditTextLayout = (TextInputLayout) view.findViewById(R.id.keyserver_url_edit_text_layout); + mVerifyKeyserverCheckBox = (CheckBox) view.findViewById(R.id.verify_connection_checkbox); + mOnlyTrustedKeyserverCheckBox = (CheckBox) view.findViewById(R.id.only_trusted_keyserver_checkbox); + mVerifyKeyserverCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mOnlyTrustedKeyserverCheckBox.setEnabled(isChecked); + } + }); switch (mDialogAction) { case ADD: { @@ -212,6 +224,8 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On positiveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + mKeyserverEditTextLayout.setErrorEnabled(false); + // behaviour same for edit and add final String keyserverUrl = mKeyserverEditText.getText().toString(); if (mVerifyKeyserverCheckBox.isChecked()) { @@ -220,13 +234,20 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On OrbotHelper.DialogActions dialogActions = new OrbotHelper.DialogActions() { @Override public void onOrbotStarted() { - verifyConnection(keyserverUrl, - proxyPrefs.parcelableProxy.getProxy()); + verifyConnection( + keyserverUrl, + proxyPrefs.parcelableProxy.getProxy(), + mOnlyTrustedKeyserverCheckBox.isChecked() + ); } @Override public void onNeutralButton() { - verifyConnection(keyserverUrl, null); + verifyConnection( + keyserverUrl, + null, + mOnlyTrustedKeyserverCheckBox.isChecked() + ); } @Override @@ -236,7 +257,11 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On }; if (OrbotHelper.putOrbotInRequiredState(dialogActions, getActivity())) { - verifyConnection(keyserverUrl, proxyPrefs.parcelableProxy.getProxy()); + verifyConnection( + keyserverUrl, + proxyPrefs.parcelableProxy.getProxy(), + mOnlyTrustedKeyserverCheckBox.isChecked() + ); } } else { dismiss(); @@ -272,14 +297,28 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On sendMessageToHandler(MESSAGE_OKAY, data); } - public void verificationFailed(FailureReason reason) { - Bundle data = new Bundle(); - data.putSerializable(MESSAGE_FAILURE_REASON, reason); + public void verificationFailed(FailureReason failureReason) { + switch (failureReason) { + case CONNECTION_FAILED: { + mKeyserverEditTextLayout.setError( + getString(R.string.add_keyserver_connection_failed)); + break; + } + case INVALID_URL: { + mKeyserverEditTextLayout.setError( + getString(R.string.add_keyserver_invalid_url)); + break; + } + case NO_PINNED_CERTIFICATE: { + mKeyserverEditTextLayout.setError( + getString(R.string.add_keyserver_keyserver_not_trusted)); + break; + } + } - sendMessageToHandler(MESSAGE_VERIFICATION_FAILED, data); } - public void verifyConnection(String keyserver, final Proxy proxy) { + public void verifyConnection(String keyserver, final Proxy proxy, final boolean onlyTrustedKeyserver) { new AsyncTask<String, Void, FailureReason>() { ProgressDialog mProgressDialog; @@ -288,7 +327,7 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On @Override protected void onPreExecute() { mProgressDialog = new ProgressDialog(getActivity()); - mProgressDialog.setMessage(getString(R.string.progress_verifying_keyserver_url)); + mProgressDialog.setMessage(getString(R.string.progress_verifying_keyserver_connection)); mProgressDialog.setCancelable(false); mProgressDialog.show(); } @@ -316,7 +355,18 @@ public class AddEditKeyserverDialogFragment extends DialogFragment implements On Log.d("Converted URL", newKeyserver.toString()); OkHttpClient client = HkpKeyserver.getClient(newKeyserver.toURL(), proxy); - TlsHelper.pinCertificateIfNecessary(client, newKeyserver.toURL()); + + // don't follow any redirects + client.setFollowRedirects(false); + client.setFollowSslRedirects(false); + + if (onlyTrustedKeyserver + && !TlsHelper.usePinnedCertificateIfAvailable(client, newKeyserver.toURL())) { + Log.w(Constants.TAG, "No pinned certificate for this host in OpenKeychain's assets."); + reason = FailureReason.NO_PINNED_CERTIFICATE; + return reason; + } + client.newCall(new Request.Builder().url(newKeyserver.toURL()).build()).execute(); } catch (TlsHelper.TlsHelperException e) { reason = FailureReason.CONNECTION_FAILED; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java deleted file mode 100644 index 84774ae5e..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (C) 2012-2014 Dominik Schürmann <dominik@dominikschuermann.de> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * 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 org.sufficientlysecure.keychain.ui.dialog; - -import android.app.Activity; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; -import android.support.v4.app.DialogFragment; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.TextView; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.util.FileHelper; -import org.sufficientlysecure.keychain.util.Log; - -import java.io.File; - -/** - * This is a file chooser dialog no longer used with KitKat - */ -public class FileDialogFragment extends DialogFragment { - private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_TITLE = "title"; - private static final String ARG_MESSAGE = "message"; - private static final String ARG_DEFAULT_FILE = "default_file"; - private static final String ARG_CHECKBOX_TEXT = "checkbox_text"; - - public static final int MESSAGE_OKAY = 1; - - public static final String MESSAGE_DATA_FILE = "file"; - public static final String MESSAGE_DATA_CHECKED = "checked"; - - private Messenger mMessenger; - - private EditText mFilename; - private ImageButton mBrowse; - private CheckBox mCheckBox; - private TextView mMessageTextView; - - private File mFile; - - private static final int REQUEST_CODE = 0x00007004; - - /** - * Creates new instance of this file dialog fragment - */ - public static FileDialogFragment newInstance(Messenger messenger, String title, String message, - File defaultFile, String checkboxText) { - FileDialogFragment frag = new FileDialogFragment(); - Bundle args = new Bundle(); - args.putParcelable(ARG_MESSENGER, messenger); - - args.putString(ARG_TITLE, title); - args.putString(ARG_MESSAGE, message); - args.putString(ARG_DEFAULT_FILE, defaultFile.getAbsolutePath()); - args.putString(ARG_CHECKBOX_TEXT, checkboxText); - - frag.setArguments(args); - - return frag; - } - - /** - * Creates dialog - */ - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final Activity activity = getActivity(); - - mMessenger = getArguments().getParcelable(ARG_MESSENGER); - - String title = getArguments().getString(ARG_TITLE); - String message = getArguments().getString(ARG_MESSAGE); - mFile = new File(getArguments().getString(ARG_DEFAULT_FILE)); - if (!mFile.isAbsolute()) { - // We use OK dir by default - mFile = new File(Constants.Path.APP_DIR.getAbsolutePath(), mFile.getName()); - } - String checkboxText = getArguments().getString(ARG_CHECKBOX_TEXT); - - LayoutInflater inflater = (LayoutInflater) activity - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - CustomAlertDialogBuilder alert = new CustomAlertDialogBuilder(activity); - alert.setTitle(title); - - View view = inflater.inflate(R.layout.file_dialog, null); - - mMessageTextView = (TextView) view.findViewById(R.id.message); - mMessageTextView.setText(message); - - mFilename = (EditText) view.findViewById(R.id.input); - mFilename.setText(mFile.getName()); - mBrowse = (ImageButton) view.findViewById(R.id.btn_browse); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - mBrowse.setVisibility(View.GONE); - } else { - mBrowse.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - // only .asc or .gpg files - // setting it to text/plain prevents Cynaogenmod's file manager from selecting asc - // or gpg types! - FileHelper.saveDocumentKitKat( - FileDialogFragment.this, "*/*", mFile.getName(), REQUEST_CODE); - } - }); - } - - mCheckBox = (CheckBox) view.findViewById(R.id.checkbox); - if (checkboxText == null) { - mCheckBox.setEnabled(false); - mCheckBox.setVisibility(View.GONE); - } else { - mCheckBox.setEnabled(true); - mCheckBox.setVisibility(View.VISIBLE); - mCheckBox.setText(checkboxText); - mCheckBox.setChecked(true); - } - - alert.setView(view); - - alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - dismiss(); - - String currentFilename = mFilename.getText().toString(); - if (currentFilename == null || currentFilename.isEmpty()) { - // No file is like pressing cancel, UI: maybe disable positive button in this case? - return; - } - - if (mFile == null || currentFilename.startsWith("/")) { - mFile = new File(currentFilename); - } else if (!mFile.getName().equals(currentFilename)) { - // We update our File object if user changed name! - mFile = new File(mFile.getParentFile(), currentFilename); - } - - boolean checked = mCheckBox.isEnabled() && mCheckBox.isChecked(); - - // return resulting data back to activity - Bundle data = new Bundle(); - data.putString(MESSAGE_DATA_FILE, mFile.getAbsolutePath()); - data.putBoolean(MESSAGE_DATA_CHECKED, checked); - - sendMessageToHandler(MESSAGE_OKAY, data); - } - }); - - alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int id) { - dismiss(); - } - }); - return alert.show(); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode & 0xFFFF) { - case REQUEST_CODE: { - if (resultCode == Activity.RESULT_OK && data != null) { - File file = new File(data.getData().getPath()); - if (file.getParentFile().exists()) { - mFile = file; - mFilename.setText(mFile.getName()); - } else { - Notify.create(getActivity(), R.string.no_file_selected, Notify.Style.ERROR).show(); - } - } - - break; - } - - default: - super.onActivityResult(requestCode, resultCode, data); - - break; - } - } - - /** - * Send message back to handler which is initialized in a activity - * - * @param what Message integer you want to send - */ - private void sendMessageToHandler(Integer what, Bundle data) { - Message msg = Message.obtain(); - msg.what = what; - if (data != null) { - msg.setData(data); - } - - try { - mMessenger.send(msg); - } catch (RemoteException e) { - Log.w(Constants.TAG, "Exception sending message, Is handler present?", e); - } catch (NullPointerException e) { - Log.w(Constants.TAG, "Messenger is null!", e); - } - } -} |