diff options
author | Christian Schneppe <christian@pix-art.de> | 2016-12-18 21:38:07 +0100 |
---|---|---|
committer | Christian Schneppe <christian@pix-art.de> | 2016-12-18 21:38:07 +0100 |
commit | 09b3ffd482251ce7ef2031f445d81879e22cfa93 (patch) | |
tree | 1f096f3d990f0882728911ccbbaac25e160451f0 /src | |
parent | 08534f519d3b3da073ba73432c92e95accaafef9 (diff) |
show warning dialog beforing verifying keys via a link
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/de/pixart/messenger/ui/StartConversationActivity.java | 257 | ||||
-rw-r--r-- | src/main/java/de/pixart/messenger/utils/XmppUri.java | 16 | ||||
-rw-r--r-- | src/main/res/layout/dialog_verify_fingerprints.xml | 25 | ||||
-rw-r--r-- | src/main/res/values/strings.xml | 3 |
4 files changed, 192 insertions, 109 deletions
diff --git a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java index 9a589e34b..edbb3856b 100644 --- a/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java +++ b/src/main/java/de/pixart/messenger/ui/StartConversationActivity.java @@ -29,7 +29,6 @@ import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.Editable; import android.text.TextWatcher; -import android.util.Log; import android.util.Pair; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -80,6 +79,8 @@ import de.pixart.messenger.xmpp.jid.Jid; public class StartConversationActivity extends XmppActivity implements OnRosterUpdate, OnUpdateBlocklist { + private final int REQUEST_SYNC_CONTACTS = 0x3b28cf; + private final int REQUEST_CREATE_CONFERENCE = 0x3b39da; public int conference_context_id; public int contact_context_id; private Tab mContactsTab; @@ -96,10 +97,8 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU private Invite mPendingInvite = null; private EditText mSearchEditText; private AtomicBoolean mRequestedContactsPermission = new AtomicBoolean(false); - private final int REQUEST_SYNC_CONTACTS = 0x3b28cf; - private final int REQUEST_CREATE_CONFERENCE = 0x3b39da; private Dialog mCurrentDialog = null; - + private boolean mHideOfflineContacts = false; private MenuItem.OnActionExpandListener mOnActionExpandListener = new MenuItem.OnActionExpandListener() { @Override @@ -126,7 +125,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU return true; } }; - private boolean mHideOfflineContacts = false; private TabListener mTabListener = new TabListener() { @Override @@ -205,6 +203,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU }; private String mInitialJid; private Pair<Integer, Intent> mPostponedActivityResult; + private Toast mToast; private UiCallback<Conversation> mAdhocConferenceCallback = new UiCallback<Conversation>() { @Override public void success(final Conversation conversation) { @@ -232,7 +231,22 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } }; - private Toast mToast; + + public static void populateAccountSpinner(Context context, List<String> accounts, Spinner spinner) { + if (accounts.size() > 0) { + ArrayAdapter<String> adapter = new ArrayAdapter<>(context, R.layout.simple_list_item, accounts); + adapter.setDropDownViewResource(R.layout.simple_list_item); + spinner.setAdapter(adapter); + spinner.setEnabled(true); + } else { + ArrayAdapter<String> adapter = new ArrayAdapter<>(context, + R.layout.simple_list_item, + Arrays.asList(new String[]{context.getString(R.string.no_accounts)})); + adapter.setDropDownViewResource(R.layout.simple_list_item); + spinner.setAdapter(adapter); + spinner.setEnabled(false); + } + } protected void hideToast() { if (mToast != null) { @@ -420,7 +434,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } else { xmppConnectionService.createContact(contact); if (invite != null && invite.hasFingerprints()) { - xmppConnectionService.verifyFingerprints(contact,invite.getFingerprints()); + xmppConnectionService.verifyFingerprints(contact, invite.getFingerprints()); } switchToConversation(contact, invite == null ? null : invite.getBody()); return true; @@ -568,22 +582,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU switchToConversation(conversation, body, false); } - public static void populateAccountSpinner(Context context, List<String> accounts, Spinner spinner) { - if (accounts.size() > 0) { - ArrayAdapter<String> adapter = new ArrayAdapter<>(context, R.layout.simple_list_item, accounts); - adapter.setDropDownViewResource(R.layout.simple_list_item); - spinner.setAdapter(adapter); - spinner.setEnabled(true); - } else { - ArrayAdapter<String> adapter = new ArrayAdapter<>(context, - R.layout.simple_list_item, - Arrays.asList(new String[]{context.getString(R.string.no_accounts)})); - adapter.setDropDownViewResource(R.layout.simple_list_item); - spinner.setAdapter(adapter); - spinner.setEnabled(false); - } - } - @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.start_conversation, menu); @@ -624,7 +622,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU showCreateConferenceDialog(); return true; case R.id.action_scan_qr_code: - new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC","QR_CODE")); + new IntentIntegrator(this).initiateScan(Arrays.asList("AZTEC", "QR_CODE")); return true; case R.id.action_hide_offline: mHideOfflineContacts = !item.isChecked(); @@ -786,12 +784,15 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU if (this.mPendingInvite != null) { mPendingInvite.invite(); this.mPendingInvite = null; + filter(null); } else if (!handleIntent(getIntent())) { if (mSearchEditText != null) { filter(mSearchEditText.getText().toString()); } else { filter(null); } + } else { + filter(null); } setIntent(null); } @@ -810,15 +811,13 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU case Intent.ACTION_VIEW: Uri uri = intent.getData(); if (uri != null) { - Log.d(Config.LOGTAG, "received uri=" + intent.getData()); - return new Invite(intent.getData()).invite(); + return new Invite(intent.getData(), false).invite(); } else { return false; } case NfcAdapter.ACTION_NDEF_DISCOVERED: for (Parcelable message : getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) { if (message instanceof NdefMessage) { - Log.d(Config.LOGTAG, "received message=" + message); for (NdefRecord record : ((NdefMessage) message).getRecords()) { switch (record.getTnf()) { case NdefRecord.TNF_WELL_KNOWN: @@ -854,7 +853,7 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU if (invite.isMuc()) { Conversation muc = xmppConnectionService.findFirstMuc(invite.getJid()); if (muc != null) { - switchToConversation(muc,invite.getBody(),false); + switchToConversation(muc, invite.getBody(), false); return true; } else { showJoinConferenceDialog(invite.getJid().toBareJid().toString()); @@ -865,10 +864,14 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU return false; } else if (contacts.size() == 1) { Contact contact = contacts.get(0); - if (invite.hasFingerprints()) { - xmppConnectionService.verifyFingerprints(contact, invite.getFingerprints()); + if (!invite.isSafeSource() && invite.hasFingerprints()) { + displayVerificationWarningDialog(contact, invite); + } else { + if (invite.hasFingerprints()) { + xmppConnectionService.verifyFingerprints(contact, invite.getFingerprints()); + } + switchToConversation(contact, invite.getBody()); } - switchToConversation(contact,invite.getBody()); return true; } else { if (mMenuSearchView != null) { @@ -883,6 +886,40 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } } + private void displayVerificationWarningDialog(final Contact contact, final Invite invite) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.verify_omemo_keys); + View view = getLayoutInflater().inflate(R.layout.dialog_verify_fingerprints, null); + final CheckBox isTrustedSource = (CheckBox) view.findViewById(R.id.trusted_source); + TextView warning = (TextView) view.findViewById(R.id.warning); + warning.setText(getString(R.string.verifying_omemo_keys_trusted_source, contact.getJid().toBareJid().toString(), contact.getDisplayName())); + builder.setView(view); + builder.setPositiveButton(R.string.confirm, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (isTrustedSource.isChecked() && invite.hasFingerprints()) { + xmppConnectionService.verifyFingerprints(contact, invite.getFingerprints()); + } + switchToConversation(contact, invite.getBody()); + } + }); + builder.setNegativeButton(R.string.cancel, new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + StartConversationActivity.this.finish(); + } + }); + AlertDialog dialog = builder.create(); + dialog.setCanceledOnTouchOutside(false); + dialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + StartConversationActivity.this.finish(); + } + }); + dialog.show(); + } + protected void filter(String needle) { if (xmppConnectionServiceBound) { this.filterContacts(needle); @@ -940,83 +977,6 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } } - public class ListPagerAdapter extends PagerAdapter { - FragmentManager fragmentManager; - MyListFragment[] fragments; - - public ListPagerAdapter(FragmentManager fm) { - fragmentManager = fm; - fragments = new MyListFragment[2]; - } - - public void requestFocus(int pos) { - if (fragments.length > pos) { - fragments[pos].getListView().requestFocus(); - } - } - - @Override - public void destroyItem(ViewGroup container, int position, Object object) { - assert (0 <= position && position < fragments.length); - FragmentTransaction trans = fragmentManager.beginTransaction(); - trans.remove(fragments[position]); - trans.commit(); - fragments[position] = null; - } - - @Override - public Fragment instantiateItem(ViewGroup container, int position) { - Fragment fragment = getItem(position); - FragmentTransaction trans = fragmentManager.beginTransaction(); - trans.add(container.getId(), fragment, "fragment:" + position); - trans.commit(); - return fragment; - } - - @Override - public int getCount() { - return fragments.length; - } - - @Override - public boolean isViewFromObject(View view, Object fragment) { - return ((Fragment) fragment).getView() == view; - } - - public Fragment getItem(int position) { - assert (0 <= position && position < fragments.length); - if (fragments[position] == null) { - final MyListFragment listFragment = new MyListFragment(); - if (position == 1) { - listFragment.setListAdapter(mConferenceAdapter); - listFragment.setContextMenu(R.menu.conference_context); - listFragment.setOnListItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView<?> arg0, View arg1, - int position, long arg3) { - openConversationForBookmark(position); - } - }); - } else { - - listFragment.setListAdapter(mContactsAdapter); - listFragment.setContextMenu(R.menu.contact_context); - listFragment.setOnListItemClickListener(new OnItemClickListener() { - - @Override - public void onItemClick(AdapterView<?> arg0, View arg1, - int position, long arg3) { - openConversationForContact(position); - } - }); - } - fragments[position] = listFragment; - } - return fragments[position]; - } - } - public static class MyListFragment extends ListFragment { private AdapterView.OnItemClickListener mOnItemClickListener; private int mResContextMenu; @@ -1099,6 +1059,83 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU } } + public class ListPagerAdapter extends PagerAdapter { + FragmentManager fragmentManager; + MyListFragment[] fragments; + + public ListPagerAdapter(FragmentManager fm) { + fragmentManager = fm; + fragments = new MyListFragment[2]; + } + + public void requestFocus(int pos) { + if (fragments.length > pos) { + fragments[pos].getListView().requestFocus(); + } + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + assert (0 <= position && position < fragments.length); + FragmentTransaction trans = fragmentManager.beginTransaction(); + trans.remove(fragments[position]); + trans.commit(); + fragments[position] = null; + } + + @Override + public Fragment instantiateItem(ViewGroup container, int position) { + Fragment fragment = getItem(position); + FragmentTransaction trans = fragmentManager.beginTransaction(); + trans.add(container.getId(), fragment, "fragment:" + position); + trans.commit(); + return fragment; + } + + @Override + public int getCount() { + return fragments.length; + } + + @Override + public boolean isViewFromObject(View view, Object fragment) { + return ((Fragment) fragment).getView() == view; + } + + public Fragment getItem(int position) { + assert (0 <= position && position < fragments.length); + if (fragments[position] == null) { + final MyListFragment listFragment = new MyListFragment(); + if (position == 1) { + listFragment.setListAdapter(mConferenceAdapter); + listFragment.setContextMenu(R.menu.conference_context); + listFragment.setOnListItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, + int position, long arg3) { + openConversationForBookmark(position); + } + }); + } else { + + listFragment.setListAdapter(mContactsAdapter); + listFragment.setContextMenu(R.menu.contact_context); + listFragment.setOnListItemClickListener(new OnItemClickListener() { + + @Override + public void onItemClick(AdapterView<?> arg0, View arg1, + int position, long arg3) { + openConversationForContact(position); + } + }); + } + fragments[position] = listFragment; + } + return fragments[position]; + } + } + private class Invite extends XmppUri { public Invite(final Uri uri) { @@ -1109,6 +1146,10 @@ public class StartConversationActivity extends XmppActivity implements OnRosterU super(uri); } + public Invite(Uri uri, boolean safeSource) { + super(uri, safeSource); + } + boolean invite() { if (getJid() != null) { return handleJid(this); diff --git a/src/main/java/de/pixart/messenger/utils/XmppUri.java b/src/main/java/de/pixart/messenger/utils/XmppUri.java index 10fa0324b..b8b9233fd 100644 --- a/src/main/java/de/pixart/messenger/utils/XmppUri.java +++ b/src/main/java/de/pixart/messenger/utils/XmppUri.java @@ -18,6 +18,7 @@ public class XmppUri { protected String fingerprint; protected List<Fingerprint> fingerprints = new ArrayList<>(); private String body; + protected boolean safeSource = true; public static final String OMEMO_URI_PARAM = "omemo-sid-"; public static final String OTR_URI_PARAM = "otr-fingerprint"; @@ -42,6 +43,15 @@ public class XmppUri { return "xmpp".equalsIgnoreCase(scheme); } + public XmppUri(Uri uri, boolean safeSource) { + this.safeSource = safeSource; + parse(uri); + } + + public boolean isSafeSource() { + return safeSource; + } + protected void parse(Uri uri) { String scheme = uri.getScheme(); String host = uri.getHost(); @@ -86,8 +96,12 @@ public class XmppUri { } protected List<Fingerprint> parseFingerprints(String query) { + return parseFingerprints(query, ';'); + } + + protected List<Fingerprint> parseFingerprints(String query, char seperator) { List<Fingerprint> fingerprints = new ArrayList<>(); - String[] pairs = query == null ? new String[0] : query.split(";"); + String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator)); for (String pair : pairs) { String[] parts = pair.split("=", 2); if (parts.length == 2) { diff --git a/src/main/res/layout/dialog_verify_fingerprints.xml b/src/main/res/layout/dialog_verify_fingerprints.xml new file mode 100644 index 000000000..6ae4a54f7 --- /dev/null +++ b/src/main/res/layout/dialog_verify_fingerprints.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingLeft="?attr/dialog_horizontal_padding" + android:paddingRight="?attr/dialog_horizontal_padding" + android:paddingBottom="?attr/dialog_vertical_padding" + android:paddingTop="?attr/dialog_vertical_padding"> + + <TextView + android:id="@+id/warning" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textSize="?attr/TextSizeBody" + android:textColor="?attr/colorAccent"/> + <CheckBox + android:layout_marginTop="8dp" + android:id="@+id/trusted_source" + android:layout_width="wrap_content" + android:textColor="?attr/colorAccent" + android:layout_height="wrap_content" + android:text="@string/i_followed_this_link_from_a_trusted_source" /> + +</LinearLayout>
\ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d7e1e93a7..416c9b84c 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -724,4 +724,7 @@ <string name="not_trusted">Untrusted</string> <string name="invalid_barcode">Invalid barcode</string> <string name="verify_with_qr_code">verify with barcode</string> + <string name="i_followed_this_link_from_a_trusted_source">I followed this link from a trusted source</string> + <string name="verifying_omemo_keys_trusted_source">You are about to verify the OMEMO keys form %1$s after clicking a link. This is only secure if you followed this link from a trusted source where only %2$s could have published this link.</string> + <string name="verify_omemo_keys">Verify OMEMO keys</string> </resources> |