made otr a little bit more solid when there is no presence subscription
This commit is contained in:
parent
dc02137106
commit
0e5a0a07fd
|
@ -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>
|
|
@ -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 doesn’t 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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue