From 3833e6dfef8c7a06982ad7783f89c28d27d83bfe Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 2 Jan 2015 01:21:14 +0100 Subject: improved OTR verification part one --- .../eu/siacs/conversations/crypto/OtrEngine.java | 6 +- .../eu/siacs/conversations/entities/Contact.java | 2 +- .../siacs/conversations/entities/Conversation.java | 31 +- .../conversations/persistance/DatabaseBackend.java | 6 +- .../conversations/ui/ContactDetailsActivity.java | 6 +- .../conversations/ui/ConversationActivity.java | 37 +++ .../conversations/ui/ConversationFragment.java | 20 +- .../siacs/conversations/ui/VerifyOTRActivity.java | 300 ++++++++++-------- .../java/eu/siacs/conversations/utils/XmppUri.java | 2 +- .../siacs/conversations/xmpp/XmppConnection.java | 4 +- src/main/res/layout/activity_verify_otr.xml | 334 +++++++++------------ src/main/res/values/strings.xml | 7 + 12 files changed, 403 insertions(+), 352 deletions(-) (limited to 'src/main') diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java index 3894e205..64434631 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java @@ -34,7 +34,7 @@ import net.java.otr4j.crypto.OtrCryptoException; import net.java.otr4j.session.InstanceTag; import net.java.otr4j.session.SessionID; -public class OtrEngine implements OtrEngineHost { +public class OtrEngine extends OtrCryptoEngineImpl implements OtrEngineHost { private Account account; private OtrPolicy otrPolicy; @@ -258,10 +258,10 @@ public class OtrEngine implements OtrEngineHost { Conversation conversation = this.mXmppConnectionService.find(this.account,jid); if (conversation!=null) { if (approved) { - conversation.getContact().addOtrFingerprint(CryptoHelper.prettifyFingerprint(fingerprint)); + conversation.getContact().addOtrFingerprint(fingerprint); } conversation.smp().hint = null; - conversation.smp().status = Conversation.Smp.STATUS_FINISHED; + conversation.smp().status = Conversation.Smp.STATUS_VERIFIED; mXmppConnectionService.updateConversationUi(); mXmppConnectionService.syncRosterToDisk(conversation.getAccount()); } diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index af26981e..698e0322 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -453,7 +453,7 @@ public class Contact implements ListItem, Blockable { public String getShareableUri() { if (getOtrFingerprints().size() >= 1) { String otr = getOtrFingerprints().get(0); - return "xmpp:" + getJid().toBareJid().toString() + "?otr-fingerprint=" + otr.replace(" ", ""); + return "xmpp:" + getJid().toBareJid().toString() + "?otr-fingerprint=" + otr; } else { return "xmpp:" + getJid().toBareJid().toString(); } diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 1f9afa65..a88984fb 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -436,30 +436,29 @@ public class Conversation extends AbstractEntity implements Blockable { return this.otrSession != null; } - public String getOtrFingerprint() { + public synchronized String getOtrFingerprint() { if (this.otrFingerprint == null) { try { - if (getOtrSession() == null) { - return ""; + if (getOtrSession() == null || getOtrSession().getSessionStatus() != SessionStatus.ENCRYPTED) { + return null; } - DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession() - .getRemotePublicKey(); - StringBuilder builder = new StringBuilder( - new OtrCryptoEngineImpl().getFingerprint(remotePubKey)); - builder.insert(8, " "); - builder.insert(17, " "); - builder.insert(26, " "); - builder.insert(35, " "); - this.otrFingerprint = builder.toString(); + DSAPublicKey remotePubKey = (DSAPublicKey) getOtrSession().getRemotePublicKey(); + this.otrFingerprint = getAccount().getOtrEngine().getFingerprint(remotePubKey); } catch (final OtrCryptoException | UnsupportedOperationException ignored) { - + return null; } } return this.otrFingerprint; } - public void verifyOtrFingerprint() { - getContact().addOtrFingerprint(getOtrFingerprint()); + public boolean verifyOtrFingerprint() { + final String fingerprint = getOtrFingerprint(); + if (fingerprint != null) { + getContact().addOtrFingerprint(fingerprint); + return true; + } else { + return false; + } } public boolean isOtrFingerprintVerified() { @@ -708,7 +707,7 @@ public class Conversation extends AbstractEntity implements Blockable { public static final int STATUS_CONTACT_REQUESTED = 1; public static final int STATUS_WE_REQUESTED = 2; public static final int STATUS_FAILED = 3; - public static final int STATUS_FINISHED = 4; + public static final int STATUS_VERIFIED = 4; public String secret = null; public String hint = null; diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 7d29314b..5fa61491 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -22,7 +22,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 12; + private static final int DATABASE_VERSION = 13; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -126,6 +126,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.SERVER_MSG_ID + " TEXT"); } + if (oldVersion < 13 && newVersion >= 13) { + db.execSQL("delete from "+Contact.TABLENAME); + db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL"); + } } public static synchronized DatabaseBackend getInstance(Context context) { diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index b195f2f1..657ae75b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -37,6 +37,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.ListItem; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; +import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.jid.InvalidJidException; @@ -315,7 +316,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd .findViewById(R.id.button_remove); remove.setVisibility(View.VISIBLE); keyType.setText("OTR Fingerprint"); - key.setText(otrFingerprint); + key.setText(CryptoHelper.prettifyFingerprint(otrFingerprint)); keys.addView(view); remove.setOnClickListener(new OnClickListener() { @@ -396,8 +397,7 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd public void onClick(DialogInterface dialog, int which) { if (contact.deleteOtrFingerprint(fingerprint)) { populateView(); - xmppConnectionService.syncRosterToDisk(contact - .getAccount()); + xmppConnectionService.syncRosterToDisk(contact.getAccount()); } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index c4c3c354..71074d3d 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -27,6 +27,8 @@ import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.Toast; +import net.java.otr4j.session.SessionStatus; + import java.util.ArrayList; import java.util.List; @@ -555,6 +557,41 @@ public class ConversationActivity extends XmppActivity attachFilePopup.show(); } + public void verifyOtrSessionDialog(final Conversation conversation, View view) { + if (!conversation.hasValidOtrSession() || conversation.getOtrSession().getSessionStatus() != SessionStatus.ENCRYPTED) { + Toast.makeText(this, R.string.otr_session_not_started, Toast.LENGTH_LONG).show(); + return; + } + if (view == null) { + return; + } + PopupMenu popup = new PopupMenu(this, view); + popup.inflate(R.menu.verification_choices); + popup.setOnMenuItemClickListener(new OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + Intent intent = new Intent(ConversationActivity.this, VerifyOTRActivity.class); + intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT); + intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString()); + intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString()); + switch (menuItem.getItemId()) { + case R.id.scan_fingerprint: + intent.putExtra("mode",VerifyOTRActivity.MODE_SCAN_FINGERPRINT); + break; + case R.id.ask_question: + intent.putExtra("mode",VerifyOTRActivity.MODE_ASK_QUESTION); + break; + case R.id.manual_verification: + intent.putExtra("mode",VerifyOTRActivity.MODE_MANUAL_VERIFICATION); + break; + } + startActivity(intent); + return true; + } + }); + popup.show(); + } + protected void selectEncryptionDialog(final Conversation conversation) { View menuItemView = findViewById(R.id.action_security); if (menuItemView == null) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 39dfd4db..c3b47d76 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -204,13 +204,7 @@ public class ConversationFragment extends Fragment { @Override public void onClick(View v) { - if (conversation.getOtrFingerprint() != null) { - Intent intent = new Intent(getActivity(), VerifyOTRActivity.class); - intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT); - intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString()); - intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString()); - startActivity(intent); - } + activity.verifyOtrSessionDialog(conversation,v); } }; private ConcurrentLinkedQueue mEncryptedMessages = new ConcurrentLinkedQueue<>(); @@ -796,7 +790,17 @@ public class ConversationFragment extends Fragment { protected void makeFingerprintWarning() { if (conversation.smpRequested()) { - showSnackbar(R.string.smp_requested, R.string.verify, clickToVerify); + showSnackbar(R.string.smp_requested, R.string.verify, new OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(activity, VerifyOTRActivity.class); + intent.setAction(VerifyOTRActivity.ACTION_VERIFY_CONTACT); + intent.putExtra("contact", conversation.getContact().getJid().toBareJid().toString()); + intent.putExtra("account", conversation.getAccount().getJid().toBareJid().toString()); + intent.putExtra("mode",VerifyOTRActivity.MODE_ANSWER_QUESTION); + startActivity(intent); + } + }); } else if (conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!conversation.isOtrFingerprintVerified())) { showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify); diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java index e5775ab0..8fffbaac 100644 --- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -1,14 +1,15 @@ package eu.siacs.conversations.ui; +import android.app.ActionBar; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -32,57 +33,56 @@ import eu.siacs.conversations.xmpp.jid.Jid; public class VerifyOTRActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate { public static final String ACTION_VERIFY_CONTACT = "verify_contact"; + public static final int MODE_SCAN_FINGERPRINT = - 0x0502; + public static final int MODE_ASK_QUESTION = 0x0503; + public static final int MODE_ANSWER_QUESTION = 0x0504; + public static final int MODE_MANUAL_VERIFICATION = 0x0505; - private RelativeLayout mVerificationAreaOne; - private RelativeLayout mVerificationAreaTwo; - private TextView mErrorNoSession; - private TextView mRemoteJid; + private LinearLayout mManualVerificationArea; + private LinearLayout mSmpVerificationArea; private TextView mRemoteFingerprint; private TextView mYourFingerprint; - private EditText mSharedSecretHint; - private EditText mSharedSecretSecret; - private Button mButtonScanQrCode; - private Button mButtonShowQrCode; - private Button mButtonSharedSecretPositive; - private Button mButtonSharedSecretNegative; + private TextView mVerificationExplain; private TextView mStatusMessage; + private TextView mSharedSecretHint; + private EditText mSharedSecretHintEditable; + private EditText mSharedSecretSecret; + private Button mLeftButton; + private Button mRightButton; private Account mAccount; private Conversation mConversation; + private int mode = MODE_MANUAL_VERIFICATION; + private XmppUri mPendingUri = null; private DialogInterface.OnClickListener mVerifyFingerprintListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int click) { mConversation.verifyOtrFingerprint(); - updateView(); xmppConnectionService.syncRosterToDisk(mConversation.getAccount()); + Toast.makeText(VerifyOTRActivity.this,R.string.verified,Toast.LENGTH_SHORT).show(); + finish(); } }; - private View.OnClickListener mShowQrCodeListener = new View.OnClickListener() { - @Override - public void onClick(final View view) { - showQrCode(); - } - }; - - private View.OnClickListener mScanQrCodeListener = new View.OnClickListener() { - - @Override - public void onClick(View view) { - new IntentIntegrator(VerifyOTRActivity.this).initiateScan(); - } - - }; - private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() { @Override public void onClick(final View view) { if (isAccountOnline()) { - final String question = mSharedSecretHint.getText().toString(); + final String question = mSharedSecretHintEditable.getText().toString(); final String secret = mSharedSecretSecret.getText().toString(); - initSmp(question, secret); - updateView(); + if (question.trim().isEmpty()) { + mSharedSecretHintEditable.requestFocus(); + mSharedSecretHintEditable.setError(getString(R.string.shared_secret_hint_should_not_be_empty)); + } else if (secret.trim().isEmpty()) { + mSharedSecretSecret.requestFocus(); + mSharedSecretSecret.setError(getString(R.string.shared_secret_can_not_be_empty)); + } else { + mSharedSecretSecret.setError(null); + mSharedSecretHintEditable.setError(null); + initSmp(question, secret); + updateView(); + } } } }; @@ -100,7 +100,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer @Override public void onClick(View view) { if (isAccountOnline()) { - final String question = mSharedSecretHint.getText().toString(); + final String question = mSharedSecretHintEditable.getText().toString(); final String secret = mSharedSecretSecret.getText().toString(); respondSmp(question, secret); updateView(); @@ -124,14 +124,14 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } }; - private XmppUri mPendingUri = null; - protected boolean initSmp(final String question, final String secret) { final Session session = mConversation.getOtrSession(); if (session!=null) { try { session.initSmp(question, secret); mConversation.smp().status = Conversation.Smp.STATUS_WE_REQUESTED; + mConversation.smp().secret = secret; + mConversation.smp().hint = question; return true; } catch (OtrException e) { return false; @@ -172,15 +172,17 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } } - protected void verifyWithUri(XmppUri uri) { + protected boolean verifyWithUri(XmppUri uri) { Contact contact = mConversation.getContact(); if (this.mConversation.getContact().getJid().equals(uri.getJid()) && uri.getFingerprint() != null) { contact.addOtrFingerprint(uri.getFingerprint()); Toast.makeText(this,R.string.verified,Toast.LENGTH_SHORT).show(); updateView(); xmppConnectionService.syncRosterToDisk(contact.getAccount()); + return true; } else { Toast.makeText(this,R.string.could_not_verify_fingerprint,Toast.LENGTH_SHORT).show(); + return false; } } @@ -194,7 +196,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } protected boolean handleIntent(Intent intent) { - if (intent.getAction().equals(ACTION_VERIFY_CONTACT)) { + if (intent != null && intent.getAction().equals(ACTION_VERIFY_CONTACT)) { try { this.mAccount = this.xmppConnectionService.findAccountByJid(Jid.fromString(intent.getExtras().getString("account"))); } catch (final InvalidJidException ignored) { @@ -208,6 +210,11 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } catch (final InvalidJidException ignored) { return false; } + this.mode = intent.getIntExtra("mode", MODE_MANUAL_VERIFICATION); + if (this.mode == MODE_SCAN_FINGERPRINT) { + new IntentIntegrator(this).initiateScan(); + return false; + } return true; } else { return false; @@ -223,9 +230,12 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer XmppUri uri = new XmppUri(data); if (xmppConnectionServiceBound) { verifyWithUri(uri); + finish(); } else { this.mPendingUri = uri; } + } else { + finish(); } } super.onActivityResult(requestCode, requestCode, intent); @@ -234,84 +244,139 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer @Override protected void onBackendConnected() { if (handleIntent(getIntent())) { - if (mPendingUri!=null) { - verifyWithUri(mPendingUri); - mPendingUri = null; - } updateView(); + } else if (mPendingUri!=null) { + verifyWithUri(mPendingUri); + finish(); + mPendingUri = null; } + setIntent(null); } protected void updateView() { if (this.mConversation.hasValidOtrSession()) { + final ActionBar actionBar = getActionBar(); + this.mVerificationExplain.setText(R.string.no_otr_session_found); invalidateOptionsMenu(); - this.mVerificationAreaOne.setVisibility(View.VISIBLE); - this.mVerificationAreaTwo.setVisibility(View.VISIBLE); - this.mErrorNoSession.setVisibility(View.GONE); - this.mYourFingerprint.setText(CryptoHelper.prettifyFingerprint(this.mAccount.getOtrFingerprint())); - this.mRemoteFingerprint.setText(this.mConversation.getOtrFingerprint()); - this.mRemoteJid.setText(this.mConversation.getContact().getJid().toBareJid().toString()); - Conversation.Smp smp = mConversation.smp(); - Session session = mConversation.getOtrSession(); - if (mConversation.isOtrFingerprintVerified()) { - deactivateButton(mButtonScanQrCode, R.string.verified); - } else { - activateButton(mButtonScanQrCode, R.string.scan_qr_code, mScanQrCodeListener); + switch(this.mode) { + case MODE_ASK_QUESTION: + if (actionBar != null ) { + actionBar.setTitle(R.string.ask_question); + } + this.updateViewAskQuestion(); + break; + case MODE_ANSWER_QUESTION: + if (actionBar != null ) { + actionBar.setTitle(R.string.smp_requested); + } + this.updateViewAnswerQuestion(); + break; + case MODE_MANUAL_VERIFICATION: + default: + if (actionBar != null ) { + actionBar.setTitle(R.string.manually_verify); + } + this.updateViewManualVerification(); + break; } - if (smp.status == Conversation.Smp.STATUS_NONE) { - activateButton(mButtonSharedSecretPositive, R.string.create, mCreateSharedSecretListener); - deactivateButton(mButtonSharedSecretNegative, R.string.cancel); - this.mSharedSecretHint.setFocusableInTouchMode(true); - this.mSharedSecretSecret.setFocusableInTouchMode(true); - this.mSharedSecretSecret.setText(""); - this.mSharedSecretHint.setText(""); - this.mSharedSecretHint.setVisibility(View.VISIBLE); - this.mSharedSecretSecret.setVisibility(View.VISIBLE); + } else { + this.mManualVerificationArea.setVisibility(View.GONE); + this.mSmpVerificationArea.setVisibility(View.GONE); + } + } + + protected void updateViewManualVerification() { + this.mVerificationExplain.setText(R.string.manual_verification_explanation); + this.mManualVerificationArea.setVisibility(View.VISIBLE); + this.mSmpVerificationArea.setVisibility(View.GONE); + this.mYourFingerprint.setText(CryptoHelper.prettifyFingerprint(this.mAccount.getOtrFingerprint())); + this.mRemoteFingerprint.setText(CryptoHelper.prettifyFingerprint(this.mConversation.getOtrFingerprint())); + if (this.mConversation.isOtrFingerprintVerified()) { + deactivateButton(this.mRightButton,R.string.verified); + activateButton(this.mLeftButton,R.string.cancel,this.mFinishListener); + } else { + activateButton(this.mLeftButton,R.string.cancel,this.mFinishListener); + activateButton(this.mRightButton,R.string.verify, new View.OnClickListener() { + @Override + public void onClick(View view) { + showManuallyVerifyDialog(); + } + }); + } + } + + protected void updateViewAskQuestion() { + this.mManualVerificationArea.setVisibility(View.GONE); + this.mSmpVerificationArea.setVisibility(View.VISIBLE); + this.mVerificationExplain.setText(R.string.smp_explain_question); + final int smpStatus = this.mConversation.smp().status; + switch (smpStatus) { + case Conversation.Smp.STATUS_WE_REQUESTED: this.mStatusMessage.setVisibility(View.GONE); - } else if (smp.status == Conversation.Smp.STATUS_CONTACT_REQUESTED) { - this.mSharedSecretHint.setFocusable(false); - this.mSharedSecretHint.setText(smp.hint); - this.mSharedSecretSecret.setFocusableInTouchMode(true); - this.mSharedSecretHint.setVisibility(View.VISIBLE); + this.mSharedSecretHintEditable.setVisibility(View.VISIBLE); this.mSharedSecretSecret.setVisibility(View.VISIBLE); + this.mSharedSecretHintEditable.setText(this.mConversation.smp().hint); + this.mSharedSecretSecret.setText(this.mConversation.smp().secret); + this.activateButton(this.mLeftButton, R.string.cancel, this.mCancelSharedSecretListener); + this.deactivateButton(this.mRightButton, R.string.in_progress); + break; + case Conversation.Smp.STATUS_FAILED: this.mStatusMessage.setVisibility(View.GONE); - deactivateButton(mButtonSharedSecretNegative, R.string.cancel); - activateButton(mButtonSharedSecretPositive, R.string.respond, mRespondSharedSecretListener); - } else if (smp.status == Conversation.Smp.STATUS_FAILED) { - activateButton(mButtonSharedSecretNegative, R.string.cancel, mFinishListener); - activateButton(mButtonSharedSecretPositive, R.string.try_again, mRetrySharedSecretListener); - this.mSharedSecretHint.setVisibility(View.GONE); + this.mSharedSecretHintEditable.setVisibility(View.VISIBLE); + this.mSharedSecretSecret.setVisibility(View.VISIBLE); + this.mSharedSecretSecret.requestFocus(); + this.mSharedSecretSecret.setError(getString(R.string.secrets_do_not_match)); + this.deactivateButton(this.mLeftButton, R.string.cancel); + this.activateButton(this.mRightButton, R.string.try_again, this.mRetrySharedSecretListener); + break; + case Conversation.Smp.STATUS_VERIFIED: + this.mSharedSecretHintEditable.setText(""); + this.mSharedSecretHintEditable.setVisibility(View.GONE); + this.mSharedSecretSecret.setText(""); this.mSharedSecretSecret.setVisibility(View.GONE); this.mStatusMessage.setVisibility(View.VISIBLE); - this.mStatusMessage.setText(R.string.secrets_do_not_match); - this.mStatusMessage.setTextColor(getWarningTextColor()); - } else if (smp.status == Conversation.Smp.STATUS_FINISHED) { - this.mSharedSecretHint.setText(""); + this.deactivateButton(this.mLeftButton, R.string.cancel); + this.activateButton(this.mRightButton, R.string.finish, this.mFinishListener); + break; + default: + this.mStatusMessage.setVisibility(View.GONE); + this.mSharedSecretHintEditable.setVisibility(View.VISIBLE); + this.mSharedSecretSecret.setVisibility(View.VISIBLE); + this.activateButton(this.mLeftButton,R.string.cancel,this.mFinishListener); + this.activateButton(this.mRightButton, R.string.ask_question, this.mCreateSharedSecretListener); + break; + } + } + + protected void updateViewAnswerQuestion() { + this.mManualVerificationArea.setVisibility(View.GONE); + this.mSmpVerificationArea.setVisibility(View.VISIBLE); + this.mVerificationExplain.setText(R.string.smp_explain_answer); + this.mSharedSecretHintEditable.setVisibility(View.GONE); + this.mSharedSecretHint.setVisibility(View.VISIBLE); + this.deactivateButton(this.mLeftButton, R.string.cancel); + final int smpStatus = this.mConversation.smp().status; + switch (smpStatus) { + case Conversation.Smp.STATUS_CONTACT_REQUESTED: + this.mStatusMessage.setVisibility(View.GONE); + this.mSharedSecretHint.setText(this.mConversation.smp().hint); + this.activateButton(this.mRightButton,R.string.respond,this.mRespondSharedSecretListener); + break; + case Conversation.Smp.STATUS_VERIFIED: + this.mSharedSecretHintEditable.setText(""); + this.mSharedSecretHintEditable.setVisibility(View.GONE); this.mSharedSecretHint.setVisibility(View.GONE); this.mSharedSecretSecret.setText(""); this.mSharedSecretSecret.setVisibility(View.GONE); this.mStatusMessage.setVisibility(View.VISIBLE); - this.mStatusMessage.setTextColor(getPrimaryColor()); - deactivateButton(mButtonSharedSecretNegative, R.string.cancel); - if (mConversation.isOtrFingerprintVerified()) { - activateButton(mButtonSharedSecretPositive, R.string.finish, mFinishListener); - this.mStatusMessage.setText(R.string.verified); - } else { - activateButton(mButtonSharedSecretPositive,R.string.reset,mRetrySharedSecretListener); - this.mStatusMessage.setText(R.string.secret_accepted); - } - } else if (session != null && session.isSmpInProgress()) { - deactivateButton(mButtonSharedSecretPositive, R.string.in_progress); - activateButton(mButtonSharedSecretNegative, R.string.cancel, mCancelSharedSecretListener); - this.mSharedSecretHint.setVisibility(View.VISIBLE); - this.mSharedSecretSecret.setVisibility(View.VISIBLE); - this.mSharedSecretHint.setFocusable(false); - this.mSharedSecretSecret.setFocusable(false); - } - } else { - this.mVerificationAreaOne.setVisibility(View.GONE); - this.mVerificationAreaTwo.setVisibility(View.GONE); - this.mErrorNoSession.setVisibility(View.VISIBLE); + this.activateButton(this.mRightButton, R.string.finish, this.mFinishListener); + break; + case Conversation.Smp.STATUS_FAILED: + default: + this.mSharedSecretSecret.requestFocus(); + this.mSharedSecretSecret.setError(getString(R.string.secrets_do_not_match)); + this.activateButton(this.mRightButton,R.string.finish,this.mFinishListener); + break; } } @@ -334,39 +399,16 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer super.onCreate(savedInstanceState); setContentView(R.layout.activity_verify_otr); this.mRemoteFingerprint = (TextView) findViewById(R.id.remote_fingerprint); - this.mRemoteJid = (TextView) findViewById(R.id.remote_jid); this.mYourFingerprint = (TextView) findViewById(R.id.your_fingerprint); - this.mButtonSharedSecretNegative = (Button) findViewById(R.id.button_shared_secret_negative); - this.mButtonSharedSecretPositive = (Button) findViewById(R.id.button_shared_secret_positive); - this.mButtonScanQrCode = (Button) findViewById(R.id.button_scan_qr_code); - this.mButtonShowQrCode = (Button) findViewById(R.id.button_show_qr_code); - this.mButtonShowQrCode.setOnClickListener(this.mShowQrCodeListener); + this.mLeftButton = (Button) findViewById(R.id.left_button); + this.mRightButton = (Button) findViewById(R.id.right_button); + this.mVerificationExplain = (TextView) findViewById(R.id.verification_explanation); + this.mStatusMessage = (TextView) findViewById(R.id.status_message); this.mSharedSecretSecret = (EditText) findViewById(R.id.shared_secret_secret); - this.mSharedSecretHint = (EditText) findViewById(R.id.shared_secret_hint); - this.mStatusMessage= (TextView) findViewById(R.id.status_message); - this.mVerificationAreaOne = (RelativeLayout) findViewById(R.id.verification_area_one); - this.mVerificationAreaTwo = (RelativeLayout) findViewById(R.id.verification_area_two); - this.mErrorNoSession = (TextView) findViewById(R.id.error_no_session); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.verify_otr, menu); - if (mConversation != null && mConversation.isOtrFingerprintVerified()) { - MenuItem manuallyVerifyItem = menu.findItem(R.id.manually_verify); - manuallyVerifyItem.setVisible(false); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem menuItem) { - if (menuItem.getItemId() == R.id.manually_verify) { - showManuallyVerifyDialog(); - return true; - } else { - return super.onOptionsItemSelected(menuItem); - } + this.mSharedSecretHintEditable = (EditText) findViewById(R.id.shared_secret_hint_editable); + this.mSharedSecretHint = (TextView) findViewById(R.id.shared_secret_hint); + this.mManualVerificationArea = (LinearLayout) findViewById(R.id.manual_verification_area); + this.mSmpVerificationArea = (LinearLayout) findViewById(R.id.smp_verification_area); } private void showManuallyVerifyDialog() { diff --git a/src/main/java/eu/siacs/conversations/utils/XmppUri.java b/src/main/java/eu/siacs/conversations/utils/XmppUri.java index d7c3bce5..aacb6362 100644 --- a/src/main/java/eu/siacs/conversations/utils/XmppUri.java +++ b/src/main/java/eu/siacs/conversations/utils/XmppUri.java @@ -53,7 +53,7 @@ public class XmppUri { final String NEEDLE = "otr-fingerprint="; int index = query.indexOf(NEEDLE); if (index >= 0 && query.length() >= (NEEDLE.length() + index + 40)) { - return CryptoHelper.prettifyFingerprint(query.substring(index + NEEDLE.length(), index + NEEDLE.length() + 40)); + return query.substring(index + NEEDLE.length(), index + NEEDLE.length() + 40); } else { return null; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0d65e547..c9a478d4 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -576,8 +576,8 @@ public class XmppConnection implements Runnable { auth.setAttribute("xmlns", "urn:ietf:params:xml:ns:xmpp-sasl"); if (mechanisms.contains("SCRAM-SHA-1")) { saslMechanism = new ScramSha1(tagWriter, account, mXmppConnectionService.getRNG()); - } else if (mechanisms.contains("DIGEST-MD5")) { - saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); + //} else if (mechanisms.contains("DIGEST-MD5")) { + // saslMechanism = new DigestMd5(tagWriter, account, mXmppConnectionService.getRNG()); } else if (mechanisms.contains("PLAIN")) { saslMechanism = new Plain(tagWriter, account); } diff --git a/src/main/res/layout/activity_verify_otr.xml b/src/main/res/layout/activity_verify_otr.xml index 73539e0e..28e5e5ed 100644 --- a/src/main/res/layout/activity_verify_otr.xml +++ b/src/main/res/layout/activity_verify_otr.xml @@ -1,189 +1,147 @@ - - - - - - - - - - - - - - - - -