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="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="unable_to_decrypt_otr_message">Unable to decrypt OTR message</string>
</resources>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -325,7 +325,7 @@ public class EditAccountActivity extends XmppActivity {
this.mServerInfoPep.setText(R.string.server_info_unavailable);
}
String fingerprint = this.mAccount
.getOtrFingerprint(getApplicationContext());
.getOtrFingerprint(xmppConnectionService);
if (fingerprint != null) {
this.mOtrFingerprintHeadline.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,
R.string.missing_presence_updates,
Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
toast.show();
}
conversation.setNextPresence(null);

View File

@ -495,6 +495,11 @@ public class MessageAdapter extends ArrayAdapter<Message> {
}
} else if (item.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) {
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 {
displayTextMessage(viewHolder, item);
}