From 8740b55d37ce62e686afbf5d302fb49498ab6ab7 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 10 Nov 2014 19:23:54 +0100 Subject: initial smp support --- .../eu/siacs/conversations/crypto/OtrEngine.java | 72 ++++-- .../siacs/conversations/entities/Conversation.java | 30 ++- .../conversations/ui/ConversationFragment.java | 16 +- .../siacs/conversations/ui/VerifyOTRActivity.java | 264 +++++++++++++++++++++ .../eu/siacs/conversations/ui/XmppActivity.java | 2 + .../eu/siacs/conversations/utils/UIHelper.java | 34 --- 6 files changed, 356 insertions(+), 62 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java index 912eea77..8b2b704a 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java @@ -18,13 +18,18 @@ import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; import net.java.otr4j.OtrEngineHost; import net.java.otr4j.OtrException; import net.java.otr4j.OtrPolicy; import net.java.otr4j.OtrPolicyImpl; +import net.java.otr4j.crypto.OtrCryptoEngineImpl; +import net.java.otr4j.crypto.OtrCryptoException; import net.java.otr4j.session.InstanceTag; import net.java.otr4j.session.SessionID; @@ -92,9 +97,18 @@ public class OtrEngine implements OtrEngineHost { } @Override - public void askForSecret(SessionID arg0, InstanceTag arg1, String arg2) { - // TODO Auto-generated method stub - + public void askForSecret(SessionID id, InstanceTag instanceTag, String question) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().hint = question; + conversation.smp().status = Conversation.Smp.STATUS_CONTACT_REQUESTED; + mXmppConnectionService.updateConversationUi(); + } + } catch (InvalidJidException e) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": smp in invalid session "+id.toString()); + } } @Override @@ -110,8 +124,11 @@ public class OtrEngine implements OtrEngineHost { @Override public byte[] getLocalFingerprintRaw(SessionID arg0) { - // TODO Auto-generated method stub - return null; + try { + return new OtrCryptoEngineImpl().getFingerprintRaw(getPublicKey()); + } catch (OtrCryptoException e) { + return null; + } } public PublicKey getPublicKey() { @@ -187,20 +204,31 @@ public class OtrEngine implements OtrEngineHost { @Override public void showError(SessionID arg0, String arg1) throws OtrException { - // TODO Auto-generated method stub - + Log.d(Config.LOGTAG,"show error"); } @Override - public void smpAborted(SessionID arg0) throws OtrException { - // TODO Auto-generated method stub + public void smpAborted(SessionID id) throws OtrException { + setSmpStatus(id, Conversation.Smp.STATUS_NONE); + } + + private void setSmpStatus(SessionID id, int status) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().status = status; + mXmppConnectionService.updateConversationUi(); + } + } catch (final InvalidJidException ignored) { + } } @Override - public void smpError(SessionID arg0, int arg1, boolean arg2) + public void smpError(SessionID id, int arg1, boolean arg2) throws OtrException { - throw new OtrException(new Exception("smp error")); + setSmpStatus(id, Conversation.Smp.STATUS_NONE); } @Override @@ -211,19 +239,29 @@ public class OtrEngine implements OtrEngineHost { @Override public void unreadableMessageReceived(SessionID arg0) throws OtrException { + Log.d(Config.LOGTAG,"unreadable message received"); throw new OtrException(new Exception("unreadable message received")); } @Override - public void unverify(SessionID arg0, String arg1) { - // TODO Auto-generated method stub - + public void unverify(SessionID id, String arg1) { + setSmpStatus(id, Conversation.Smp.STATUS_FAILED); } @Override - public void verify(SessionID arg0, String arg1, boolean arg2) { - // TODO Auto-generated method stub - + public void verify(SessionID id, String arg1, boolean arg2) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().hint = null; + conversation.smp().status = Conversation.Smp.STATUS_VERIFIED; + conversation.verifyOtrFingerprint(); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.syncRosterToDisk(conversation.getAccount()); + } + } catch (final InvalidJidException ignored) { + } } } diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index c8dedd7b..622e0f83 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -63,13 +63,12 @@ public class Conversation extends AbstractEntity { private transient SessionImpl otrSession; private transient String otrFingerprint = null; + private Smp mSmp = new Smp(); private String nextMessage; private transient MucOptions mucOptions = null; - // private transient String latestMarkableMessageId; - private byte[] symmetricKey; private Bookmark bookmark; @@ -271,6 +270,13 @@ public class Conversation extends AbstractEntity { public void resetOtrSession() { this.otrFingerprint = null; this.otrSession = null; + this.mSmp.hint = null; + this.mSmp.secret = null; + this.mSmp.status = Smp.STATUS_NONE; + } + + public Smp smp() { + return mSmp; } public void startOtrIfNeeded() { @@ -330,6 +336,14 @@ public class Conversation extends AbstractEntity { return this.otrFingerprint; } + public void verifyOtrFingerprint() { + getContact().addOtrFingerprint(getOtrFingerprint()); + } + + public boolean isOtrFingerprintVerified() { + return getContact().getOtrFingerprints().contains(getOtrFingerprint()); + } + public synchronized MucOptions getMucOptions() { if (this.mucOptions == null) { this.mucOptions = new MucOptions(this); @@ -503,4 +517,16 @@ public class Conversation extends AbstractEntity { this.messages.addAll(index, messages); } } + + public class Smp { + public static final int STATUS_NONE = 0; + 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_VERIFIED = 4; + + public String secret = null; + public String hint = null; + public int status = 0; + } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 63d740c3..5a536987 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -680,23 +680,21 @@ public class ConversationFragment extends Fragment { } protected void makeFingerprintWarning() { - Set knownFingerprints = conversation.getContact() - .getOtrFingerprints(); if (conversation.hasValidOtrSession() && (!conversation.isMuted()) - && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints - .contains(conversation.getOtrFingerprint()))) { + && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) + && (!conversation.isOtrFingerprintVerified())) { showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, new OnClickListener() { @Override public void onClick(View v) { if (conversation.getOtrFingerprint() != null) { - AlertDialog dialog = UIHelper - .getVerifyFingerprintDialog( - (ConversationActivity) getActivity(), - conversation, snackbar); - dialog.show(); + 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); } } }); diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java new file mode 100644 index 00000000..45aec7d7 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -0,0 +1,264 @@ +package eu.siacs.conversations.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import net.java.otr4j.OtrException; +import net.java.otr4j.crypto.OtrCryptoException; +import net.java.otr4j.session.Session; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Contact; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; + +public class VerifyOTRActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate { + + public static final String ACTION_VERIFY_CONTACT = "verify_contact"; + + private TextView mRemoteJid; + private TextView mRemoteFingerprint; + private TextView mYourFingerprint; + private EditText mSharedSecretHint; + private EditText mSharedSecretSecret; + private Button mButtonVerifyFingerprint; + private Button mButtonSharedSecretPositive; + private Button mButtonSharedSecretNegative; + private TextView mStatusMessage; + private Account mAccount; + private Conversation mConversation; + private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() { + @Override + public void onClick(final View view) { + final String question = mSharedSecretHint.getText().toString(); + final String secret = mSharedSecretSecret.getText().toString(); + if (!initSmp(question,secret)) { + Toast.makeText(getApplicationContext(),"smp failed",Toast.LENGTH_SHORT).show(); + } + updateView(); + } + }; + private View.OnClickListener mCancelSharedSecretListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + abortSmp(); + } + }; + private View.OnClickListener mRespondSharedSecretListener = new View.OnClickListener() { + + @Override + public void onClick(View view) { + final String question = mSharedSecretHint.getText().toString(); + final String secret = mSharedSecretSecret.getText().toString(); + respondSmp(question,secret); + updateView(); + } + }; + private View.OnClickListener mRetrySharedSecretListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + mConversation.smp().status = Conversation.Smp.STATUS_NONE; + mConversation.smp().hint = null; + mConversation.smp().secret = null; + updateView(); + } + }; + private View.OnClickListener mFinishListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + mConversation.smp().status = Conversation.Smp.STATUS_NONE; + finish(); + } + }; + + 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; + return true; + } catch (OtrException e) { + return false; + } + } else { + return false; + } + } + + protected boolean abortSmp() { + final Session session = mConversation.getOtrSession(); + if (session!=null) { + try { + session.abortSmp(); + mConversation.smp().status = Conversation.Smp.STATUS_NONE; + return true; + } catch (OtrException e) { + return false; + } + } else { + return false; + } + } + + protected boolean respondSmp(final String question, final String secret) { + final Session session = mConversation.getOtrSession(); + if (session!=null) { + try { + session.respondSmp(question,secret); + return true; + } catch (OtrException e) { + return false; + } + } else { + return false; + } + } + + protected boolean handleIntent(Intent intent) { + if (getIntent().getAction().equals(ACTION_VERIFY_CONTACT)) { + try { + this.mAccount = this.xmppConnectionService.findAccountByJid(Jid.fromString(getIntent().getExtras().getString("account"))); + } catch (final InvalidJidException ignored) { + return false; + } + try { + this.mConversation = this.xmppConnectionService.find(this.mAccount,Jid.fromString(getIntent().getExtras().getString("contact"))); + if (this.mConversation == null) { + return false; + } + } catch (final InvalidJidException ignored) { + return false; + } + return true; + } else { + return false; + } + } + + @Override + protected void onBackendConnected() { + if (handleIntent(getIntent())) { + updateView(); + } + this.xmppConnectionService.setOnConversationListChangedListener(this); + } + + protected void updateView() { + this.mYourFingerprint.setText(this.mAccount.getOtrFingerprint(xmppConnectionService)); + 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 (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); + 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.mSharedSecretSecret.setVisibility(View.VISIBLE); + 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.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_VERIFIED) { + this.mSharedSecretHint.setVisibility(View.GONE); + this.mSharedSecretSecret.setVisibility(View.GONE); + this.mStatusMessage.setVisibility(View.VISIBLE); + this.mStatusMessage.setText(R.string.verified); + this.mStatusMessage.setTextColor(getPrimaryColor()); + deactivateButton(mButtonSharedSecretNegative, R.string.cancel); + activateButton(mButtonSharedSecretPositive, R.string.finish, mFinishListener); + } 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); + } + } + + protected void activateButton(Button button, int text, View.OnClickListener listener) { + button.setEnabled(true); + button.setTextColor(getPrimaryTextColor()); + button.setText(text); + button.setOnClickListener(listener); + } + + protected void deactivateButton(Button button, int text) { + button.setEnabled(false); + button.setTextColor(getSecondaryTextColor()); + button.setText(text); + button.setOnClickListener(null); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + 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.mButtonVerifyFingerprint = (Button) findViewById(R.id.button_verify_fingerprint); + 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); + } + + @Override + protected String getShareableUri() { + if (mAccount!=null) { + return "xmpp:"+mAccount.getJid().toBareJid(); + } else { + return ""; + } + } + + @Override + protected void onStop() { + if (xmppConnectionServiceBound) { + xmppConnectionService.removeOnConversationListChangedListener(); + } + super.onStop(); + } + + @Override + public void onConversationUpdate() { + runOnUiThread(new Runnable() { + @Override + public void run() { + updateView(); + } + }); + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 78d7956a..67da7714 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -639,6 +639,7 @@ public abstract class XmppActivity extends Activity { } protected Bitmap createQrCodeBitmap(String input, int size) { + Log.d(Config.LOGTAG,"qr code requested size: "+size); try { final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter(); final Hashtable hints = new Hashtable<>(); @@ -654,6 +655,7 @@ public abstract class XmppActivity extends Activity { } } final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Log.d(Config.LOGTAG,"output size: "+width+"x"+height); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return bitmap; } catch (final WriterException e) { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 1def052e..c4832d60 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -148,40 +148,6 @@ public class UIHelper { mNotificationManager.notify(1111, notification); } - @SuppressLint("InflateParams") - public static AlertDialog getVerifyFingerprintDialog( - final ConversationActivity activity, - final Conversation conversation, final View msg) { - final Contact contact = conversation.getContact(); - final Account account = conversation.getAccount(); - - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle("Verify fingerprint"); - LayoutInflater inflater = activity.getLayoutInflater(); - View view = inflater.inflate(R.layout.dialog_verify_otr, null); - TextView jid = (TextView) view.findViewById(R.id.verify_otr_jid); - TextView fingerprint = (TextView) view - .findViewById(R.id.verify_otr_fingerprint); - TextView yourprint = (TextView) view - .findViewById(R.id.verify_otr_yourprint); - - jid.setText(contact.getJid().toString()); - fingerprint.setText(conversation.getOtrFingerprint()); - yourprint.setText(account.getOtrFingerprint()); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Verify", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - contact.addOtrFingerprint(conversation.getOtrFingerprint()); - msg.setVisibility(View.GONE); - activity.xmppConnectionService.syncRosterToDisk(account); - } - }); - builder.setView(view); - return builder.create(); - } - private final static class EmoticonPattern { Pattern pattern; String replacement; -- cgit v1.2.3 From dc98b3dbd5ce9da547fd62ffeaf98650f5586fd5 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 10 Nov 2014 22:03:23 +0100 Subject: added snackbar to indicate smp. more error handling in verify activity --- .../siacs/conversations/entities/Conversation.java | 4 + .../conversations/ui/ConversationFragment.java | 125 ++++++++++---------- .../siacs/conversations/ui/VerifyOTRActivity.java | 128 +++++++++++++-------- 3 files changed, 144 insertions(+), 113 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 622e0f83..a9f4c0f1 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -417,6 +417,10 @@ public class Conversation extends AbstractEntity { } } + public boolean smpRequested() { + return smp().status == Smp.STATUS_CONTACT_REQUESTED; + } + public void setNextMessage(String message) { this.nextMessage = message; } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 5a536987..11f2c4fc 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -35,7 +35,6 @@ import net.java.otr4j.session.SessionStatus; import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import eu.siacs.conversations.R; @@ -53,7 +52,6 @@ import eu.siacs.conversations.ui.XmppActivity.OnValueEdited; import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; -import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jid.Jid; public class ConversationFragment extends Fragment { @@ -146,6 +144,19 @@ public class ConversationFragment extends Fragment { } } }; + protected OnClickListener clickToVerify = new OnClickListener() { + + @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); + } + } + }; private ConcurrentLinkedQueue mEncryptedMessages = new ConcurrentLinkedQueue<>(); private boolean mDecryptJobRunning = false; private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() { @@ -296,7 +307,7 @@ public class ConversationFragment extends Fragment { .getConversation()); } } - } else { + } else { Account account = message.getConversation().getAccount(); Intent intent = new Intent(activity, EditAccountActivity.class); intent.putExtra("jid", account.getJid().toBareJid().toString()); @@ -505,6 +516,39 @@ public class ConversationFragment extends Fragment { activity.switchToContactDetails(contact); } }); + } else if (conversation.getMode() == Conversation.MODE_SINGLE) { + makeFingerprintWarning(); + } else if (!conversation.getMucOptions().online() + && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { + int error = conversation.getMucOptions().getError(); + switch (error) { + case MucOptions.ERROR_NICK_IN_USE: + showSnackbar(R.string.nick_in_use, R.string.edit, + clickToMuc); + break; + case MucOptions.ERROR_ROOM_NOT_FOUND: + showSnackbar(R.string.conference_not_found, + R.string.leave, leaveMuc); + break; + case MucOptions.ERROR_PASSWORD_REQUIRED: + showSnackbar(R.string.conference_requires_password, + R.string.enter_password, enterPassword); + break; + case MucOptions.ERROR_BANNED: + showSnackbar(R.string.conference_banned, + R.string.leave, leaveMuc); + break; + case MucOptions.ERROR_MEMBERS_ONLY: + showSnackbar(R.string.conference_members_only, + R.string.leave, leaveMuc); + break; + case MucOptions.KICKED_FROM_ROOM: + showSnackbar(R.string.conference_kicked, R.string.join, + joinMuc); + break; + default: + break; + } } for (Message message : this.conversation.getMessages()) { if (message.getEncryption() == Message.ENCRYPTION_PGP @@ -526,44 +570,6 @@ public class ConversationFragment extends Fragment { updateStatusMessages(); } this.messageListAdapter.notifyDataSetChanged(); - if (conversation.getMode() == Conversation.MODE_SINGLE) { - if (messageList.size() >= 1) { - makeFingerprintWarning(); - } - } else { - if (!conversation.getMucOptions().online() - && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { - int error = conversation.getMucOptions().getError(); - switch (error) { - case MucOptions.ERROR_NICK_IN_USE: - showSnackbar(R.string.nick_in_use, R.string.edit, - clickToMuc); - break; - case MucOptions.ERROR_ROOM_NOT_FOUND: - showSnackbar(R.string.conference_not_found, - R.string.leave, leaveMuc); - break; - case MucOptions.ERROR_PASSWORD_REQUIRED: - showSnackbar(R.string.conference_requires_password, - R.string.enter_password, enterPassword); - break; - case MucOptions.ERROR_BANNED: - showSnackbar(R.string.conference_banned, - R.string.leave, leaveMuc); - break; - case MucOptions.ERROR_MEMBERS_ONLY: - showSnackbar(R.string.conference_members_only, - R.string.leave, leaveMuc); - break; - case MucOptions.KICKED_FROM_ROOM: - showSnackbar(R.string.conference_kicked, R.string.join, - joinMuc); - break; - default: - break; - } - } - } updateChatMsgHint(); if (!activity.isConversationsOverviewVisable() || !activity.isConversationsOverviewHideable()) { activity.xmppConnectionService.markRead(conversation, true); @@ -680,24 +686,11 @@ public class ConversationFragment extends Fragment { } protected void makeFingerprintWarning() { - if (conversation.hasValidOtrSession() - && (!conversation.isMuted()) - && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) + if (conversation.smpRequested()) { + showSnackbar(R.string.smp_requested, R.string.verify, clickToVerify); + } else if (conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!conversation.isOtrFingerprintVerified())) { - showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, - new OnClickListener() { - - @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); - } - } - }); + showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify); } } @@ -824,15 +817,15 @@ public class ConversationFragment extends Fragment { final ConversationActivity activity = (ConversationActivity) getActivity(); final XmppConnectionService xmppService = activity.xmppConnectionService; activity.selectPresence(message.getConversation(), - new OnPresenceSelected() { + new OnPresenceSelected() { - @Override - public void onPresenceSelected() { - message.setCounterpart(conversation.getNextCounterpart()); - xmppService.sendMessage(message); - messageSent(); - } - }); + @Override + public void onPresenceSelected() { + message.setCounterpart(conversation.getNextCounterpart()); + xmppService.sendMessage(message); + messageSent(); + } + }); } public void appendText(String text) { diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java index 45aec7d7..e9850ea4 100644 --- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -7,6 +7,7 @@ import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -27,6 +28,9 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer public static final String ACTION_VERIFY_CONTACT = "verify_contact"; + private RelativeLayout mVerificationAreaOne; + private RelativeLayout mVerificationAreaTwo; + private TextView mErrorNoSession; private TextView mRemoteJid; private TextView mRemoteFingerprint; private TextView mYourFingerprint; @@ -38,6 +42,16 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer private TextView mStatusMessage; private Account mAccount; private Conversation mConversation; + + private View.OnClickListener mVerifyFingerprintListener = new View.OnClickListener() { + + @Override + public void onClick(View view) { + mConversation.verifyOtrFingerprint(); + finish(); + } + }; + private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() { @Override public void onClick(final View view) { @@ -53,6 +67,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer @Override public void onClick(View view) { abortSmp(); + updateView(); } }; private View.OnClickListener mRespondSharedSecretListener = new View.OnClickListener() { @@ -103,6 +118,8 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer try { session.abortSmp(); mConversation.smp().status = Conversation.Smp.STATUS_NONE; + mConversation.smp().hint = null; + mConversation.smp().secret = null; return true; } catch (OtrException e) { return false; @@ -156,53 +173,67 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } protected void updateView() { - this.mYourFingerprint.setText(this.mAccount.getOtrFingerprint(xmppConnectionService)); - 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 (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); - 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.mSharedSecretSecret.setVisibility(View.VISIBLE); - 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.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_VERIFIED) { - this.mSharedSecretHint.setVisibility(View.GONE); - this.mSharedSecretSecret.setVisibility(View.GONE); - this.mStatusMessage.setVisibility(View.VISIBLE); - this.mStatusMessage.setText(R.string.verified); - this.mStatusMessage.setTextColor(getPrimaryColor()); - deactivateButton(mButtonSharedSecretNegative, R.string.cancel); - activateButton(mButtonSharedSecretPositive, R.string.finish, mFinishListener); - } 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); + if (this.mConversation.hasValidOtrSession()) { + this.mVerificationAreaOne.setVisibility(View.VISIBLE); + this.mVerificationAreaTwo.setVisibility(View.VISIBLE); + this.mErrorNoSession.setVisibility(View.GONE); + this.mYourFingerprint.setText(this.mAccount.getOtrFingerprint(xmppConnectionService)); + 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(mButtonVerifyFingerprint, R.string.verified); + } else { + activateButton(mButtonVerifyFingerprint, R.string.verify, mVerifyFingerprintListener); + } + 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); + 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.mSharedSecretSecret.setVisibility(View.VISIBLE); + 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.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_VERIFIED) { + this.mSharedSecretHint.setVisibility(View.GONE); + this.mSharedSecretSecret.setVisibility(View.GONE); + this.mStatusMessage.setVisibility(View.VISIBLE); + this.mStatusMessage.setText(R.string.verified); + this.mStatusMessage.setTextColor(getPrimaryColor()); + deactivateButton(mButtonSharedSecretNegative, R.string.cancel); + activateButton(mButtonSharedSecretPositive, R.string.finish, mFinishListener); + } 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); } } @@ -233,6 +264,9 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer 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 -- cgit v1.2.3 From 8cb97f517fcd9bdb33f07edccf27b7497653c2de Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 10 Nov 2014 23:47:04 +0100 Subject: small bug fix --- .../java/eu/siacs/conversations/ui/VerifyOTRActivity.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java index e9850ea4..d33007fb 100644 --- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -2,23 +2,18 @@ package eu.siacs.conversations.ui; import android.content.Intent; import android.os.Bundle; -import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; -import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import net.java.otr4j.OtrException; -import net.java.otr4j.crypto.OtrCryptoException; import net.java.otr4j.session.Session; -import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xmpp.jid.InvalidJidException; @@ -144,14 +139,14 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } protected boolean handleIntent(Intent intent) { - if (getIntent().getAction().equals(ACTION_VERIFY_CONTACT)) { + if (intent.getAction().equals(ACTION_VERIFY_CONTACT)) { try { - this.mAccount = this.xmppConnectionService.findAccountByJid(Jid.fromString(getIntent().getExtras().getString("account"))); + this.mAccount = this.xmppConnectionService.findAccountByJid(Jid.fromString(intent.getExtras().getString("account"))); } catch (final InvalidJidException ignored) { return false; } try { - this.mConversation = this.xmppConnectionService.find(this.mAccount,Jid.fromString(getIntent().getExtras().getString("contact"))); + this.mConversation = this.xmppConnectionService.find(this.mAccount,Jid.fromString(intent.getExtras().getString("contact"))); if (this.mConversation == null) { return false; } -- cgit v1.2.3 From 6cd2ff0d886b03079036570c74ecb70050b1de2d Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 10 Nov 2014 19:23:54 +0100 Subject: initial smp support --- .../eu/siacs/conversations/crypto/OtrEngine.java | 72 ++++-- .../siacs/conversations/entities/Conversation.java | 30 ++- .../conversations/ui/ConversationFragment.java | 16 +- .../siacs/conversations/ui/VerifyOTRActivity.java | 264 +++++++++++++++++++++ .../eu/siacs/conversations/ui/XmppActivity.java | 2 + .../eu/siacs/conversations/utils/UIHelper.java | 34 --- 6 files changed, 356 insertions(+), 62 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java index 912eea77..8b2b704a 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrEngine.java @@ -18,13 +18,18 @@ import android.util.Log; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.MessagePacket; import net.java.otr4j.OtrEngineHost; import net.java.otr4j.OtrException; import net.java.otr4j.OtrPolicy; import net.java.otr4j.OtrPolicyImpl; +import net.java.otr4j.crypto.OtrCryptoEngineImpl; +import net.java.otr4j.crypto.OtrCryptoException; import net.java.otr4j.session.InstanceTag; import net.java.otr4j.session.SessionID; @@ -92,9 +97,18 @@ public class OtrEngine implements OtrEngineHost { } @Override - public void askForSecret(SessionID arg0, InstanceTag arg1, String arg2) { - // TODO Auto-generated method stub - + public void askForSecret(SessionID id, InstanceTag instanceTag, String question) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().hint = question; + conversation.smp().status = Conversation.Smp.STATUS_CONTACT_REQUESTED; + mXmppConnectionService.updateConversationUi(); + } + } catch (InvalidJidException e) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": smp in invalid session "+id.toString()); + } } @Override @@ -110,8 +124,11 @@ public class OtrEngine implements OtrEngineHost { @Override public byte[] getLocalFingerprintRaw(SessionID arg0) { - // TODO Auto-generated method stub - return null; + try { + return new OtrCryptoEngineImpl().getFingerprintRaw(getPublicKey()); + } catch (OtrCryptoException e) { + return null; + } } public PublicKey getPublicKey() { @@ -187,20 +204,31 @@ public class OtrEngine implements OtrEngineHost { @Override public void showError(SessionID arg0, String arg1) throws OtrException { - // TODO Auto-generated method stub - + Log.d(Config.LOGTAG,"show error"); } @Override - public void smpAborted(SessionID arg0) throws OtrException { - // TODO Auto-generated method stub + public void smpAborted(SessionID id) throws OtrException { + setSmpStatus(id, Conversation.Smp.STATUS_NONE); + } + + private void setSmpStatus(SessionID id, int status) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().status = status; + mXmppConnectionService.updateConversationUi(); + } + } catch (final InvalidJidException ignored) { + } } @Override - public void smpError(SessionID arg0, int arg1, boolean arg2) + public void smpError(SessionID id, int arg1, boolean arg2) throws OtrException { - throw new OtrException(new Exception("smp error")); + setSmpStatus(id, Conversation.Smp.STATUS_NONE); } @Override @@ -211,19 +239,29 @@ public class OtrEngine implements OtrEngineHost { @Override public void unreadableMessageReceived(SessionID arg0) throws OtrException { + Log.d(Config.LOGTAG,"unreadable message received"); throw new OtrException(new Exception("unreadable message received")); } @Override - public void unverify(SessionID arg0, String arg1) { - // TODO Auto-generated method stub - + public void unverify(SessionID id, String arg1) { + setSmpStatus(id, Conversation.Smp.STATUS_FAILED); } @Override - public void verify(SessionID arg0, String arg1, boolean arg2) { - // TODO Auto-generated method stub - + public void verify(SessionID id, String arg1, boolean arg2) { + try { + final Jid jid = Jid.fromSessionID(id); + Conversation conversation = this.mXmppConnectionService.find(this.account,jid); + if (conversation!=null) { + conversation.smp().hint = null; + conversation.smp().status = Conversation.Smp.STATUS_VERIFIED; + conversation.verifyOtrFingerprint(); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.syncRosterToDisk(conversation.getAccount()); + } + } catch (final InvalidJidException ignored) { + } } } diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index c8dedd7b..622e0f83 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -63,13 +63,12 @@ public class Conversation extends AbstractEntity { private transient SessionImpl otrSession; private transient String otrFingerprint = null; + private Smp mSmp = new Smp(); private String nextMessage; private transient MucOptions mucOptions = null; - // private transient String latestMarkableMessageId; - private byte[] symmetricKey; private Bookmark bookmark; @@ -271,6 +270,13 @@ public class Conversation extends AbstractEntity { public void resetOtrSession() { this.otrFingerprint = null; this.otrSession = null; + this.mSmp.hint = null; + this.mSmp.secret = null; + this.mSmp.status = Smp.STATUS_NONE; + } + + public Smp smp() { + return mSmp; } public void startOtrIfNeeded() { @@ -330,6 +336,14 @@ public class Conversation extends AbstractEntity { return this.otrFingerprint; } + public void verifyOtrFingerprint() { + getContact().addOtrFingerprint(getOtrFingerprint()); + } + + public boolean isOtrFingerprintVerified() { + return getContact().getOtrFingerprints().contains(getOtrFingerprint()); + } + public synchronized MucOptions getMucOptions() { if (this.mucOptions == null) { this.mucOptions = new MucOptions(this); @@ -503,4 +517,16 @@ public class Conversation extends AbstractEntity { this.messages.addAll(index, messages); } } + + public class Smp { + public static final int STATUS_NONE = 0; + 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_VERIFIED = 4; + + public String secret = null; + public String hint = null; + public int status = 0; + } } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 63d740c3..5a536987 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -680,23 +680,21 @@ public class ConversationFragment extends Fragment { } protected void makeFingerprintWarning() { - Set knownFingerprints = conversation.getContact() - .getOtrFingerprints(); if (conversation.hasValidOtrSession() && (!conversation.isMuted()) - && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!knownFingerprints - .contains(conversation.getOtrFingerprint()))) { + && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) + && (!conversation.isOtrFingerprintVerified())) { showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, new OnClickListener() { @Override public void onClick(View v) { if (conversation.getOtrFingerprint() != null) { - AlertDialog dialog = UIHelper - .getVerifyFingerprintDialog( - (ConversationActivity) getActivity(), - conversation, snackbar); - dialog.show(); + 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); } } }); diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java new file mode 100644 index 00000000..45aec7d7 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -0,0 +1,264 @@ +package eu.siacs.conversations.ui; + +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import net.java.otr4j.OtrException; +import net.java.otr4j.crypto.OtrCryptoException; +import net.java.otr4j.session.Session; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Contact; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; + +public class VerifyOTRActivity extends XmppActivity implements XmppConnectionService.OnConversationUpdate { + + public static final String ACTION_VERIFY_CONTACT = "verify_contact"; + + private TextView mRemoteJid; + private TextView mRemoteFingerprint; + private TextView mYourFingerprint; + private EditText mSharedSecretHint; + private EditText mSharedSecretSecret; + private Button mButtonVerifyFingerprint; + private Button mButtonSharedSecretPositive; + private Button mButtonSharedSecretNegative; + private TextView mStatusMessage; + private Account mAccount; + private Conversation mConversation; + private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() { + @Override + public void onClick(final View view) { + final String question = mSharedSecretHint.getText().toString(); + final String secret = mSharedSecretSecret.getText().toString(); + if (!initSmp(question,secret)) { + Toast.makeText(getApplicationContext(),"smp failed",Toast.LENGTH_SHORT).show(); + } + updateView(); + } + }; + private View.OnClickListener mCancelSharedSecretListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + abortSmp(); + } + }; + private View.OnClickListener mRespondSharedSecretListener = new View.OnClickListener() { + + @Override + public void onClick(View view) { + final String question = mSharedSecretHint.getText().toString(); + final String secret = mSharedSecretSecret.getText().toString(); + respondSmp(question,secret); + updateView(); + } + }; + private View.OnClickListener mRetrySharedSecretListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + mConversation.smp().status = Conversation.Smp.STATUS_NONE; + mConversation.smp().hint = null; + mConversation.smp().secret = null; + updateView(); + } + }; + private View.OnClickListener mFinishListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + mConversation.smp().status = Conversation.Smp.STATUS_NONE; + finish(); + } + }; + + 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; + return true; + } catch (OtrException e) { + return false; + } + } else { + return false; + } + } + + protected boolean abortSmp() { + final Session session = mConversation.getOtrSession(); + if (session!=null) { + try { + session.abortSmp(); + mConversation.smp().status = Conversation.Smp.STATUS_NONE; + return true; + } catch (OtrException e) { + return false; + } + } else { + return false; + } + } + + protected boolean respondSmp(final String question, final String secret) { + final Session session = mConversation.getOtrSession(); + if (session!=null) { + try { + session.respondSmp(question,secret); + return true; + } catch (OtrException e) { + return false; + } + } else { + return false; + } + } + + protected boolean handleIntent(Intent intent) { + if (getIntent().getAction().equals(ACTION_VERIFY_CONTACT)) { + try { + this.mAccount = this.xmppConnectionService.findAccountByJid(Jid.fromString(getIntent().getExtras().getString("account"))); + } catch (final InvalidJidException ignored) { + return false; + } + try { + this.mConversation = this.xmppConnectionService.find(this.mAccount,Jid.fromString(getIntent().getExtras().getString("contact"))); + if (this.mConversation == null) { + return false; + } + } catch (final InvalidJidException ignored) { + return false; + } + return true; + } else { + return false; + } + } + + @Override + protected void onBackendConnected() { + if (handleIntent(getIntent())) { + updateView(); + } + this.xmppConnectionService.setOnConversationListChangedListener(this); + } + + protected void updateView() { + this.mYourFingerprint.setText(this.mAccount.getOtrFingerprint(xmppConnectionService)); + 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 (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); + 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.mSharedSecretSecret.setVisibility(View.VISIBLE); + 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.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_VERIFIED) { + this.mSharedSecretHint.setVisibility(View.GONE); + this.mSharedSecretSecret.setVisibility(View.GONE); + this.mStatusMessage.setVisibility(View.VISIBLE); + this.mStatusMessage.setText(R.string.verified); + this.mStatusMessage.setTextColor(getPrimaryColor()); + deactivateButton(mButtonSharedSecretNegative, R.string.cancel); + activateButton(mButtonSharedSecretPositive, R.string.finish, mFinishListener); + } 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); + } + } + + protected void activateButton(Button button, int text, View.OnClickListener listener) { + button.setEnabled(true); + button.setTextColor(getPrimaryTextColor()); + button.setText(text); + button.setOnClickListener(listener); + } + + protected void deactivateButton(Button button, int text) { + button.setEnabled(false); + button.setTextColor(getSecondaryTextColor()); + button.setText(text); + button.setOnClickListener(null); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + 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.mButtonVerifyFingerprint = (Button) findViewById(R.id.button_verify_fingerprint); + 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); + } + + @Override + protected String getShareableUri() { + if (mAccount!=null) { + return "xmpp:"+mAccount.getJid().toBareJid(); + } else { + return ""; + } + } + + @Override + protected void onStop() { + if (xmppConnectionServiceBound) { + xmppConnectionService.removeOnConversationListChangedListener(); + } + super.onStop(); + } + + @Override + public void onConversationUpdate() { + runOnUiThread(new Runnable() { + @Override + public void run() { + updateView(); + } + }); + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 9d78e222..992ff979 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -685,6 +685,7 @@ public abstract class XmppActivity extends Activity { } protected Bitmap createQrCodeBitmap(String input, int size) { + Log.d(Config.LOGTAG,"qr code requested size: "+size); try { final QRCodeWriter QR_CODE_WRITER = new QRCodeWriter(); final Hashtable hints = new Hashtable<>(); @@ -700,6 +701,7 @@ public abstract class XmppActivity extends Activity { } } final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + Log.d(Config.LOGTAG,"output size: "+width+"x"+height); bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return bitmap; } catch (final WriterException e) { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 1def052e..c4832d60 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -148,40 +148,6 @@ public class UIHelper { mNotificationManager.notify(1111, notification); } - @SuppressLint("InflateParams") - public static AlertDialog getVerifyFingerprintDialog( - final ConversationActivity activity, - final Conversation conversation, final View msg) { - final Contact contact = conversation.getContact(); - final Account account = conversation.getAccount(); - - AlertDialog.Builder builder = new AlertDialog.Builder(activity); - builder.setTitle("Verify fingerprint"); - LayoutInflater inflater = activity.getLayoutInflater(); - View view = inflater.inflate(R.layout.dialog_verify_otr, null); - TextView jid = (TextView) view.findViewById(R.id.verify_otr_jid); - TextView fingerprint = (TextView) view - .findViewById(R.id.verify_otr_fingerprint); - TextView yourprint = (TextView) view - .findViewById(R.id.verify_otr_yourprint); - - jid.setText(contact.getJid().toString()); - fingerprint.setText(conversation.getOtrFingerprint()); - yourprint.setText(account.getOtrFingerprint()); - builder.setNegativeButton("Cancel", null); - builder.setPositiveButton("Verify", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - contact.addOtrFingerprint(conversation.getOtrFingerprint()); - msg.setVisibility(View.GONE); - activity.xmppConnectionService.syncRosterToDisk(account); - } - }); - builder.setView(view); - return builder.create(); - } - private final static class EmoticonPattern { Pattern pattern; String replacement; -- cgit v1.2.3 From e33fc26cbe4f60b78cd57e9d4ceff7b3f6e3a6a0 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 10 Nov 2014 22:03:23 +0100 Subject: added snackbar to indicate smp. more error handling in verify activity --- .../siacs/conversations/entities/Conversation.java | 4 + .../conversations/ui/ConversationFragment.java | 125 ++++++++++---------- .../siacs/conversations/ui/VerifyOTRActivity.java | 128 +++++++++++++-------- 3 files changed, 144 insertions(+), 113 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 622e0f83..a9f4c0f1 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -417,6 +417,10 @@ public class Conversation extends AbstractEntity { } } + public boolean smpRequested() { + return smp().status == Smp.STATUS_CONTACT_REQUESTED; + } + public void setNextMessage(String message) { this.nextMessage = message; } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 5a536987..11f2c4fc 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -35,7 +35,6 @@ import net.java.otr4j.session.SessionStatus; import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import eu.siacs.conversations.R; @@ -53,7 +52,6 @@ import eu.siacs.conversations.ui.XmppActivity.OnValueEdited; import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; -import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.jid.Jid; public class ConversationFragment extends Fragment { @@ -146,6 +144,19 @@ public class ConversationFragment extends Fragment { } } }; + protected OnClickListener clickToVerify = new OnClickListener() { + + @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); + } + } + }; private ConcurrentLinkedQueue mEncryptedMessages = new ConcurrentLinkedQueue<>(); private boolean mDecryptJobRunning = false; private OnEditorActionListener mEditorActionListener = new OnEditorActionListener() { @@ -296,7 +307,7 @@ public class ConversationFragment extends Fragment { .getConversation()); } } - } else { + } else { Account account = message.getConversation().getAccount(); Intent intent = new Intent(activity, EditAccountActivity.class); intent.putExtra("jid", account.getJid().toBareJid().toString()); @@ -505,6 +516,39 @@ public class ConversationFragment extends Fragment { activity.switchToContactDetails(contact); } }); + } else if (conversation.getMode() == Conversation.MODE_SINGLE) { + makeFingerprintWarning(); + } else if (!conversation.getMucOptions().online() + && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { + int error = conversation.getMucOptions().getError(); + switch (error) { + case MucOptions.ERROR_NICK_IN_USE: + showSnackbar(R.string.nick_in_use, R.string.edit, + clickToMuc); + break; + case MucOptions.ERROR_ROOM_NOT_FOUND: + showSnackbar(R.string.conference_not_found, + R.string.leave, leaveMuc); + break; + case MucOptions.ERROR_PASSWORD_REQUIRED: + showSnackbar(R.string.conference_requires_password, + R.string.enter_password, enterPassword); + break; + case MucOptions.ERROR_BANNED: + showSnackbar(R.string.conference_banned, + R.string.leave, leaveMuc); + break; + case MucOptions.ERROR_MEMBERS_ONLY: + showSnackbar(R.string.conference_members_only, + R.string.leave, leaveMuc); + break; + case MucOptions.KICKED_FROM_ROOM: + showSnackbar(R.string.conference_kicked, R.string.join, + joinMuc); + break; + default: + break; + } } for (Message message : this.conversation.getMessages()) { if (message.getEncryption() == Message.ENCRYPTION_PGP @@ -526,44 +570,6 @@ public class ConversationFragment extends Fragment { updateStatusMessages(); } this.messageListAdapter.notifyDataSetChanged(); - if (conversation.getMode() == Conversation.MODE_SINGLE) { - if (messageList.size() >= 1) { - makeFingerprintWarning(); - } - } else { - if (!conversation.getMucOptions().online() - && conversation.getAccount().getStatus() == Account.STATUS_ONLINE) { - int error = conversation.getMucOptions().getError(); - switch (error) { - case MucOptions.ERROR_NICK_IN_USE: - showSnackbar(R.string.nick_in_use, R.string.edit, - clickToMuc); - break; - case MucOptions.ERROR_ROOM_NOT_FOUND: - showSnackbar(R.string.conference_not_found, - R.string.leave, leaveMuc); - break; - case MucOptions.ERROR_PASSWORD_REQUIRED: - showSnackbar(R.string.conference_requires_password, - R.string.enter_password, enterPassword); - break; - case MucOptions.ERROR_BANNED: - showSnackbar(R.string.conference_banned, - R.string.leave, leaveMuc); - break; - case MucOptions.ERROR_MEMBERS_ONLY: - showSnackbar(R.string.conference_members_only, - R.string.leave, leaveMuc); - break; - case MucOptions.KICKED_FROM_ROOM: - showSnackbar(R.string.conference_kicked, R.string.join, - joinMuc); - break; - default: - break; - } - } - } updateChatMsgHint(); if (!activity.isConversationsOverviewVisable() || !activity.isConversationsOverviewHideable()) { activity.xmppConnectionService.markRead(conversation, true); @@ -680,24 +686,11 @@ public class ConversationFragment extends Fragment { } protected void makeFingerprintWarning() { - if (conversation.hasValidOtrSession() - && (!conversation.isMuted()) - && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) + if (conversation.smpRequested()) { + showSnackbar(R.string.smp_requested, R.string.verify, clickToVerify); + } else if (conversation.hasValidOtrSession() && (conversation.getOtrSession().getSessionStatus() == SessionStatus.ENCRYPTED) && (!conversation.isOtrFingerprintVerified())) { - showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, - new OnClickListener() { - - @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); - } - } - }); + showSnackbar(R.string.unknown_otr_fingerprint, R.string.verify, clickToVerify); } } @@ -824,15 +817,15 @@ public class ConversationFragment extends Fragment { final ConversationActivity activity = (ConversationActivity) getActivity(); final XmppConnectionService xmppService = activity.xmppConnectionService; activity.selectPresence(message.getConversation(), - new OnPresenceSelected() { + new OnPresenceSelected() { - @Override - public void onPresenceSelected() { - message.setCounterpart(conversation.getNextCounterpart()); - xmppService.sendMessage(message); - messageSent(); - } - }); + @Override + public void onPresenceSelected() { + message.setCounterpart(conversation.getNextCounterpart()); + xmppService.sendMessage(message); + messageSent(); + } + }); } public void appendText(String text) { diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java index 45aec7d7..e9850ea4 100644 --- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -7,6 +7,7 @@ import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -27,6 +28,9 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer public static final String ACTION_VERIFY_CONTACT = "verify_contact"; + private RelativeLayout mVerificationAreaOne; + private RelativeLayout mVerificationAreaTwo; + private TextView mErrorNoSession; private TextView mRemoteJid; private TextView mRemoteFingerprint; private TextView mYourFingerprint; @@ -38,6 +42,16 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer private TextView mStatusMessage; private Account mAccount; private Conversation mConversation; + + private View.OnClickListener mVerifyFingerprintListener = new View.OnClickListener() { + + @Override + public void onClick(View view) { + mConversation.verifyOtrFingerprint(); + finish(); + } + }; + private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() { @Override public void onClick(final View view) { @@ -53,6 +67,7 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer @Override public void onClick(View view) { abortSmp(); + updateView(); } }; private View.OnClickListener mRespondSharedSecretListener = new View.OnClickListener() { @@ -103,6 +118,8 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer try { session.abortSmp(); mConversation.smp().status = Conversation.Smp.STATUS_NONE; + mConversation.smp().hint = null; + mConversation.smp().secret = null; return true; } catch (OtrException e) { return false; @@ -156,53 +173,67 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } protected void updateView() { - this.mYourFingerprint.setText(this.mAccount.getOtrFingerprint(xmppConnectionService)); - 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 (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); - 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.mSharedSecretSecret.setVisibility(View.VISIBLE); - 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.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_VERIFIED) { - this.mSharedSecretHint.setVisibility(View.GONE); - this.mSharedSecretSecret.setVisibility(View.GONE); - this.mStatusMessage.setVisibility(View.VISIBLE); - this.mStatusMessage.setText(R.string.verified); - this.mStatusMessage.setTextColor(getPrimaryColor()); - deactivateButton(mButtonSharedSecretNegative, R.string.cancel); - activateButton(mButtonSharedSecretPositive, R.string.finish, mFinishListener); - } 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); + if (this.mConversation.hasValidOtrSession()) { + this.mVerificationAreaOne.setVisibility(View.VISIBLE); + this.mVerificationAreaTwo.setVisibility(View.VISIBLE); + this.mErrorNoSession.setVisibility(View.GONE); + this.mYourFingerprint.setText(this.mAccount.getOtrFingerprint(xmppConnectionService)); + 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(mButtonVerifyFingerprint, R.string.verified); + } else { + activateButton(mButtonVerifyFingerprint, R.string.verify, mVerifyFingerprintListener); + } + 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); + 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.mSharedSecretSecret.setVisibility(View.VISIBLE); + 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.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_VERIFIED) { + this.mSharedSecretHint.setVisibility(View.GONE); + this.mSharedSecretSecret.setVisibility(View.GONE); + this.mStatusMessage.setVisibility(View.VISIBLE); + this.mStatusMessage.setText(R.string.verified); + this.mStatusMessage.setTextColor(getPrimaryColor()); + deactivateButton(mButtonSharedSecretNegative, R.string.cancel); + activateButton(mButtonSharedSecretPositive, R.string.finish, mFinishListener); + } 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); } } @@ -233,6 +264,9 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer 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 -- cgit v1.2.3 From 76f4cf1a73ccc3d11b1c794a802b9ff038164482 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Mon, 10 Nov 2014 23:47:04 +0100 Subject: small bug fix --- .../java/eu/siacs/conversations/ui/VerifyOTRActivity.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java index e9850ea4..d33007fb 100644 --- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -2,23 +2,18 @@ package eu.siacs.conversations.ui; import android.content.Intent; import android.os.Bundle; -import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; -import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import net.java.otr4j.OtrException; -import net.java.otr4j.crypto.OtrCryptoException; import net.java.otr4j.session.Session; -import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; -import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xmpp.jid.InvalidJidException; @@ -144,14 +139,14 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } protected boolean handleIntent(Intent intent) { - if (getIntent().getAction().equals(ACTION_VERIFY_CONTACT)) { + if (intent.getAction().equals(ACTION_VERIFY_CONTACT)) { try { - this.mAccount = this.xmppConnectionService.findAccountByJid(Jid.fromString(getIntent().getExtras().getString("account"))); + this.mAccount = this.xmppConnectionService.findAccountByJid(Jid.fromString(intent.getExtras().getString("account"))); } catch (final InvalidJidException ignored) { return false; } try { - this.mConversation = this.xmppConnectionService.find(this.mAccount,Jid.fromString(getIntent().getExtras().getString("contact"))); + this.mConversation = this.xmppConnectionService.find(this.mAccount,Jid.fromString(intent.getExtras().getString("contact"))); if (this.mConversation == null) { return false; } -- cgit v1.2.3 From d1bf9a3f6d63deaef28a1966e90c6ccd18275d30 Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Tue, 11 Nov 2014 17:42:09 +0100 Subject: use auto register for verify otr listeners --- src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java index d33007fb..3c75b501 100644 --- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -164,7 +164,6 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer if (handleIntent(getIntent())) { updateView(); } - this.xmppConnectionService.setOnConversationListChangedListener(this); } protected void updateView() { @@ -273,14 +272,6 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } } - @Override - protected void onStop() { - if (xmppConnectionServiceBound) { - xmppConnectionService.removeOnConversationListChangedListener(); - } - super.onStop(); - } - @Override public void onConversationUpdate() { runOnUiThread(new Runnable() { -- cgit v1.2.3 From f1e2be4096d1c023adc2c9eec49bcf64b9a453de Mon Sep 17 00:00:00 2001 From: iNPUTmice Date: Wed, 12 Nov 2014 12:45:59 +0100 Subject: check if account is online before doing smp --- .../siacs/conversations/ui/VerifyOTRActivity.java | 35 +++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'src/main/java/eu/siacs/conversations') diff --git a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java index 2a425d12..31884bd2 100644 --- a/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/VerifyOTRActivity.java @@ -50,29 +50,33 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer private View.OnClickListener mCreateSharedSecretListener = new View.OnClickListener() { @Override public void onClick(final View view) { - final String question = mSharedSecretHint.getText().toString(); - final String secret = mSharedSecretSecret.getText().toString(); - if (!initSmp(question,secret)) { - Toast.makeText(getApplicationContext(),"smp failed",Toast.LENGTH_SHORT).show(); + if (isAccountOnline()) { + final String question = mSharedSecretHint.getText().toString(); + final String secret = mSharedSecretSecret.getText().toString(); + initSmp(question, secret); + updateView(); } - updateView(); } }; private View.OnClickListener mCancelSharedSecretListener = new View.OnClickListener() { @Override public void onClick(View view) { - abortSmp(); - updateView(); + if (isAccountOnline()) { + abortSmp(); + updateView(); + } } }; private View.OnClickListener mRespondSharedSecretListener = new View.OnClickListener() { @Override public void onClick(View view) { - final String question = mSharedSecretHint.getText().toString(); - final String secret = mSharedSecretSecret.getText().toString(); - respondSmp(question,secret); - updateView(); + if (isAccountOnline()) { + final String question = mSharedSecretHint.getText().toString(); + final String secret = mSharedSecretSecret.getText().toString(); + respondSmp(question, secret); + updateView(); + } } }; private View.OnClickListener mRetrySharedSecretListener = new View.OnClickListener() { @@ -138,6 +142,15 @@ public class VerifyOTRActivity extends XmppActivity implements XmppConnectionSer } } + protected boolean isAccountOnline() { + if (this.mAccount.getStatus() != Account.STATUS_ONLINE) { + Toast.makeText(this,R.string.not_connected_try_again,Toast.LENGTH_SHORT).show(); + return false; + } else { + return true; + } + } + protected boolean handleIntent(Intent intent) { if (intent.getAction().equals(ACTION_VERIFY_CONTACT)) { try { -- cgit v1.2.3