made otr a little bit more solid when there is no presence subscription

This commit is contained in:
iNPUTmice 2014-09-06 18:21:31 +02:00
parent dc02137106
commit 0e5a0a07fd
9 changed files with 56 additions and 29 deletions

View file

@ -244,5 +244,6 @@
<string name="missing_presence_updates">Missing presence updates from contact</string> <string name="missing_presence_updates">Missing presence updates from contact</string>
<string name="request_presence_updates">Please request presence updates from your contact first.\n\n<small>This will be used to determine what client(s) your contact is using.</small></string> <string name="request_presence_updates">Please request presence updates from your contact first.\n\n<small>This will be used to determine what client(s) your contact is using.</small></string>
<string name="request_now">Request now</string> <string name="request_now">Request now</string>
<string name="unable_to_decrypt_otr_message">Unable to decrypt OTR message</string>
</resources> </resources>

View file

@ -19,7 +19,10 @@ import android.util.Log;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.persistance.DatabaseBackend; import eu.siacs.conversations.persistance.DatabaseBackend;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket; import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
import net.java.otr4j.OtrEngineHost; import net.java.otr4j.OtrEngineHost;
@ -28,21 +31,24 @@ import net.java.otr4j.OtrPolicy;
import net.java.otr4j.OtrPolicyImpl; import net.java.otr4j.OtrPolicyImpl;
import net.java.otr4j.session.InstanceTag; import net.java.otr4j.session.InstanceTag;
import net.java.otr4j.session.SessionID; import net.java.otr4j.session.SessionID;
import net.java.otr4j.session.SessionImpl;
import net.java.otr4j.session.SessionStatus;
public class OtrEngine implements OtrEngineHost { public class OtrEngine implements OtrEngineHost {
private Account account; private Account account;
private OtrPolicy otrPolicy; private OtrPolicy otrPolicy;
private KeyPair keyPair; private KeyPair keyPair;
private Context context; private XmppConnectionService mXmppConnectionService;
public OtrEngine(Context context, Account account) { public OtrEngine(XmppConnectionService service, Account account) {
this.account = account; this.account = account;
this.otrPolicy = new OtrPolicyImpl(); this.otrPolicy = new OtrPolicyImpl();
this.otrPolicy.setAllowV1(false); this.otrPolicy.setAllowV1(false);
this.otrPolicy.setAllowV2(true); this.otrPolicy.setAllowV2(true);
this.otrPolicy.setAllowV3(true); this.otrPolicy.setAllowV3(true);
this.keyPair = loadKey(account.getKeys()); this.keyPair = loadKey(account.getKeys());
this.mXmppConnectionService = service;
} }
private KeyPair loadKey(JSONObject keys) { private KeyPair loadKey(JSONObject keys) {
@ -102,14 +108,12 @@ public class OtrEngine implements OtrEngineHost {
@Override @Override
public void finishedSessionMessage(SessionID arg0, String arg1) public void finishedSessionMessage(SessionID arg0, String arg1)
throws OtrException { throws OtrException {
// TODO Auto-generated method stub
} }
@Override @Override
public String getFallbackMessage(SessionID arg0) { public String getFallbackMessage(SessionID arg0) {
// TODO Auto-generated method stub return "I would like to start a private (OTR encrypted) conversation but your client doesnt seem to support that";
return null;
} }
@Override @Override
@ -133,7 +137,7 @@ public class OtrEngine implements OtrEngineHost {
kg = KeyPairGenerator.getInstance("DSA"); kg = KeyPairGenerator.getInstance("DSA");
this.keyPair = kg.genKeyPair(); this.keyPair = kg.genKeyPair();
this.saveKey(); this.saveKey();
DatabaseBackend.getInstance(context).updateAccount(account); mXmppConnectionService.databaseBackend.updateAccount(account);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
Log.d(Config.LOGTAG, Log.d(Config.LOGTAG,
"error generating key pair " + e.getMessage()); "error generating key pair " + e.getMessage());
@ -171,9 +175,22 @@ public class OtrEngine implements OtrEngineHost {
} }
@Override @Override
public void messageFromAnotherInstanceReceived(SessionID arg0) { public void messageFromAnotherInstanceReceived(SessionID id) {
// TODO Auto-generated method stub String jid = id.getAccountID();
Conversation conversation = mXmppConnectionService
.findOrCreateConversation(account, jid, false);
Message error = new Message(conversation, null, Message.ENCRYPTION_OTR);
conversation.getMessages().add(error);
error.setStatus(Message.STATUS_RECEPTION_FAILED);
mXmppConnectionService.databaseBackend.createMessage(error);
SessionImpl session = conversation.getOtrSession();
if (session != null
&& session.getSessionStatus() != SessionStatus.ENCRYPTED) {
try {
session.startSession();
} catch (OtrException e) {
}
}
} }
@Override @Override

View file

@ -14,6 +14,7 @@ import org.json.JSONObject;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.OtrEngine; import eu.siacs.conversations.crypto.OtrEngine;
import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.XmppConnection;
import android.content.ContentValues; import android.content.ContentValues;
@ -230,7 +231,7 @@ public class Account extends AbstractEntity {
cursor.getString(cursor.getColumnIndex(AVATAR))); cursor.getString(cursor.getColumnIndex(AVATAR)));
} }
public OtrEngine getOtrEngine(Context context) { public OtrEngine getOtrEngine(XmppConnectionService context) {
if (otrEngine == null) { if (otrEngine == null) {
otrEngine = new OtrEngine(context, this); otrEngine = new OtrEngine(context, this);
} }
@ -283,8 +284,8 @@ public class Account extends AbstractEntity {
this.rosterVersion = version; this.rosterVersion = version;
} }
public String getOtrFingerprint(Context applicationContext) { public String getOtrFingerprint(XmppConnectionService service) {
this.getOtrEngine(applicationContext); this.getOtrEngine(service);
return this.getOtrFingerprint(); return this.getOtrFingerprint();
} }

View file

@ -4,6 +4,7 @@ import java.security.interfaces.DSAPublicKey;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.UIHelper;
import net.java.otr4j.OtrException; import net.java.otr4j.OtrException;
@ -43,7 +44,7 @@ public class Conversation extends AbstractEntity {
private int status; private int status;
private long created; private long created;
private int mode; private int mode;
private long mutedTill = 0; private long mutedTill = 0;
private String nextPresence; private String nextPresence;
@ -223,15 +224,15 @@ public class Conversation extends AbstractEntity {
this.mode = mode; this.mode = mode;
} }
public SessionImpl startOtrSession(Context context, String presence, public SessionImpl startOtrSession(XmppConnectionService service,
boolean sendStart) { String presence, boolean sendStart) {
if (this.otrSession != null) { if (this.otrSession != null) {
return this.otrSession; return this.otrSession;
} else { } else {
SessionID sessionId = new SessionID(this.getContactJid(), presence, SessionID sessionId = new SessionID(
"xmpp"); this.getContactJid().split("/")[0], presence, "xmpp");
this.otrSession = new SessionImpl(sessionId, getAccount() this.otrSession = new SessionImpl(sessionId, getAccount()
.getOtrEngine(context)); .getOtrEngine(service));
try { try {
if (sendStart) { if (sendStart) {
this.otrSession.startSession(); this.otrSession.startSession();
@ -425,7 +426,7 @@ public class Conversation extends AbstractEntity {
public void setMutedTill(long mutedTill) { public void setMutedTill(long mutedTill) {
this.mutedTill = mutedTill; this.mutedTill = mutedTill;
} }
public boolean isMuted() { public boolean isMuted() {
return SystemClock.elapsedRealtime() < this.mutedTill; return SystemClock.elapsedRealtime() < this.mutedTill;
} }

View file

@ -71,10 +71,13 @@ public class MessageParser extends AbstractParser implements
} }
updateLastseen(packet, account, true); updateLastseen(packet, account, true);
String body = packet.getBody(); String body = packet.getBody();
if (body.matches("^\\?OTRv\\d*\\?")) {
conversation.resetOtrSession();
}
if (!conversation.hasValidOtrSession()) { if (!conversation.hasValidOtrSession()) {
if (properlyAddressed) { if (properlyAddressed) {
conversation.startOtrSession( conversation.startOtrSession(
mXmppConnectionService.getApplicationContext(), mXmppConnectionService,
presence, false); presence, false);
} else { } else {
return null; return null;
@ -86,7 +89,7 @@ public class MessageParser extends AbstractParser implements
conversation.endOtrIfNeeded(); conversation.endOtrIfNeeded();
if (properlyAddressed) { if (properlyAddressed) {
conversation.startOtrSession( conversation.startOtrSession(
mXmppConnectionService.getApplicationContext(), mXmppConnectionService,
presence, false); presence, false);
} else { } else {
return null; return null;
@ -125,7 +128,7 @@ public class MessageParser extends AbstractParser implements
if (receivedId != null) { if (receivedId != null) {
mXmppConnectionService.replyWithNotAcceptable(account, packet); mXmppConnectionService.replyWithNotAcceptable(account, packet);
} }
conversation.endOtrIfNeeded(); conversation.resetOtrSession();
return null; return null;
} }
} }

View file

@ -516,7 +516,7 @@ public class XmppConnectionService extends Service {
if (message.getEncryption() == Message.ENCRYPTION_OTR) { if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasValidOtrSession() if (!conv.hasValidOtrSession()
&& (message.getPresence() != null)) { && (message.getPresence() != null)) {
conv.startOtrSession(getApplicationContext(), conv.startOtrSession(this,
message.getPresence(), true); message.getPresence(), true);
message.setStatus(Message.STATUS_WAITING); message.setStatus(Message.STATUS_WAITING);
} else if (conv.hasValidOtrSession() } else if (conv.hasValidOtrSession()
@ -536,7 +536,7 @@ public class XmppConnectionService extends Service {
if (message.getEncryption() == Message.ENCRYPTION_OTR) { if (message.getEncryption() == Message.ENCRYPTION_OTR) {
if (!conv.hasValidOtrSession() if (!conv.hasValidOtrSession()
&& (message.getPresence() != null)) { && (message.getPresence() != null)) {
conv.startOtrSession(getApplicationContext(), conv.startOtrSession(this,
message.getPresence(), true); message.getPresence(), true);
message.setStatus(Message.STATUS_WAITING); message.setStatus(Message.STATUS_WAITING);
} else if (conv.hasValidOtrSession() } else if (conv.hasValidOtrSession()
@ -577,7 +577,7 @@ public class XmppConnectionService extends Service {
.getUserID()); .getUserID());
} else if (!conv.hasValidOtrSession() } else if (!conv.hasValidOtrSession()
&& message.getPresence() != null) { && message.getPresence() != null) {
conv.startOtrSession(getApplicationContext(), conv.startOtrSession(this,
message.getPresence(), false); message.getPresence(), false);
} }
} }
@ -617,13 +617,13 @@ public class XmppConnectionService extends Service {
if ((message.getPresence() != null) if ((message.getPresence() != null)
&& (presences.has(message.getPresence()))) { && (presences.has(message.getPresence()))) {
message.getConversation().startOtrSession( message.getConversation().startOtrSession(
getApplicationContext(), message.getPresence(), this, message.getPresence(),
true); true);
} else { } else {
if (presences.size() == 1) { if (presences.size() == 1) {
String presence = presences.asStringArray()[0]; String presence = presences.asStringArray()[0];
message.getConversation().startOtrSession( message.getConversation().startOtrSession(
getApplicationContext(), presence, true); this, presence, true);
} }
} }
} else { } else {

View file

@ -325,7 +325,7 @@ public class EditAccountActivity extends XmppActivity {
this.mServerInfoPep.setText(R.string.server_info_unavailable); this.mServerInfoPep.setText(R.string.server_info_unavailable);
} }
String fingerprint = this.mAccount String fingerprint = this.mAccount
.getOtrFingerprint(getApplicationContext()); .getOtrFingerprint(xmppConnectionService);
if (fingerprint != null) { if (fingerprint != null) {
this.mOtrFingerprintHeadline.setVisibility(View.VISIBLE); this.mOtrFingerprintHeadline.setVisibility(View.VISIBLE);
this.mOtrFingerprint.setVisibility(View.VISIBLE); this.mOtrFingerprint.setVisibility(View.VISIBLE);

View file

@ -377,7 +377,6 @@ public abstract class XmppActivity extends Activity {
Toast toast = Toast.makeText(this, Toast toast = Toast.makeText(this,
R.string.missing_presence_updates, R.string.missing_presence_updates,
Toast.LENGTH_LONG); Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show(); toast.show();
} }
conversation.setNextPresence(null); conversation.setNextPresence(null);

View file

@ -495,6 +495,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} }
} else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { } else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
displayDecryptionFailed(viewHolder); displayDecryptionFailed(viewHolder);
} else if (item.getEncryption() == Message.ENCRYPTION_OTR
&& item.getStatus() == Message.STATUS_RECEPTION_FAILED
&& item.getType() == Message.TYPE_TEXT) {
displayInfoMessage(viewHolder,
R.string.unable_to_decrypt_otr_message);
} else { } else {
displayTextMessage(viewHolder, item); displayTextMessage(viewHolder, item);
} }