aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2016-12-18 21:38:07 +0100
committerChristian Schneppe <christian@pix-art.de>2016-12-18 21:38:07 +0100
commit09b3ffd482251ce7ef2031f445d81879e22cfa93 (patch)
tree1f096f3d990f0882728911ccbbaac25e160451f0 /src
parent08534f519d3b3da073ba73432c92e95accaafef9 (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.java257
-rw-r--r--src/main/java/de/pixart/messenger/utils/XmppUri.java16
-rw-r--r--src/main/res/layout/dialog_verify_fingerprints.xml25
-rw-r--r--src/main/res/values/strings.xml3
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>