From d2845e9ac1040a269401ef9d59e27bac9e7b7d5a Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 23:13:28 +0200 Subject: Refactor axolotl send processing/caching flow --- .../conversations/crypto/axolotl/AxolotlService.java | 17 ++++++++--------- .../siacs/conversations/generator/MessageGenerator.java | 5 +---- .../conversations/services/XmppConnectionService.java | 11 +++++++---- 3 files changed, 16 insertions(+), 17 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 72d1d14a0..882ead3c1 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -68,7 +68,7 @@ public class AxolotlService { private final SQLiteAxolotlStore axolotlStore; private final SessionMap sessions; private final Map> deviceIds; - private final Map messageCache; + private final Map messageCache; private final FetchStatusMap fetchStatusMap; private final SerialSingleThreadExecutor executor; @@ -1085,14 +1085,13 @@ public class AxolotlService { executor.execute(new Runnable() { @Override public void run() { - MessagePacket packet = mXmppConnectionService.getMessageGenerator() - .generateAxolotlChat(message); - if (packet == null) { + XmppAxolotlMessage axolotlMessage = encrypt(message); + if (axolotlMessage == null) { mXmppConnectionService.markMessage(message, Message.STATUS_SEND_FAILED); //mXmppConnectionService.updateConversationUi(); } else { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Generated message, caching: " + message.getUuid()); - messageCache.put(message.getUuid(), packet); + messageCache.put(message.getUuid(), axolotlMessage); mXmppConnectionService.resendMessage(message,delay); } } @@ -1108,15 +1107,15 @@ public class AxolotlService { } } - public MessagePacket fetchPacketFromCache(Message message) { - MessagePacket packet = messageCache.get(message.getUuid()); - if (packet != null) { + public XmppAxolotlMessage fetchAxolotlMessageFromCache(Message message) { + XmppAxolotlMessage axolotlMessage = messageCache.get(message.getUuid()); + if (axolotlMessage != null) { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Cache hit: " + message.getUuid()); messageCache.remove(message.getUuid()); } else { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Cache miss: " + message.getUuid()); } - return packet; + return axolotlMessage; } public XmppAxolotlMessage.XmppAxolotlPlaintextMessage processReceiving(XmppAxolotlMessage message) { diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index d3c35789e..fed92a27c 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -62,11 +62,8 @@ public class MessageGenerator extends AbstractGenerator { delay.setAttribute("stamp", mDateFormat.format(date)); } - public MessagePacket generateAxolotlChat(Message message) { + public MessagePacket generateAxolotlChat(Message message, XmppAxolotlMessage axolotlMessage) { MessagePacket packet = preparePacket(message); - AxolotlService service = message.getConversation().getAccount().getAxolotlService(); - Log.d(Config.LOGTAG, AxolotlService.getLogprefix(message.getConversation().getAccount())+"Submitting message to axolotl service for send processing..."); - XmppAxolotlMessage axolotlMessage = service.encrypt(message); if (axolotlMessage == null) { return null; } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e43b25368..e7df9e6a9 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -52,6 +52,7 @@ import de.duenndns.ssl.MemorizingTrustManager; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; +import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Blockable; import eu.siacs.conversations.entities.Bookmark; @@ -765,10 +766,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa break; } } else { - packet = account.getAxolotlService().fetchPacketFromCache(message); - if (packet == null) { + XmppAxolotlMessage axolotlMessage = account.getAxolotlService().fetchAxolotlMessageFromCache(message); + if (axolotlMessage == null) { account.getAxolotlService().prepareMessage(message,delay); message.setAxolotlFingerprint(account.getAxolotlService().getOwnPublicKey().getFingerprint().replaceAll("\\s", "")); + } else { + packet = mMessageGenerator.generateAxolotlChat(message, axolotlMessage); } } break; @@ -839,7 +842,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa @Override public void onMessageFound(Message message) { - resendMessage(message,true); + resendMessage(message, true); } }); } @@ -1851,7 +1854,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } else { MessagePacket outPacket = mMessageGenerator.generateOtrChat(message); if (outPacket != null) { - mMessageGenerator.addDelay(outPacket,message.getTimeSent()); + mMessageGenerator.addDelay(outPacket, message.getTimeSent()); message.setStatus(Message.STATUS_SEND); databaseBackend.updateMessage(message); sendMessagePacket(account, outPacket); -- cgit v1.2.3 From 971aa3a11e1077a38746cb45e7177851725be47e Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 23:16:06 +0200 Subject: Also decrypt messages from UNTRUSTED sessions --- src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 882ead3c1..b07245936 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -524,6 +524,7 @@ public class AxolotlService { byte[] plaintext = null; switch (getTrust()) { case UNDECIDED: + case UNTRUSTED: case TRUSTED: try { try { @@ -553,7 +554,6 @@ public class AxolotlService { break; case COMPROMISED: - case UNTRUSTED: default: // ignore break; -- cgit v1.2.3 From 122bc97ce24181ccd07cf9badf8d4c3b81d80c3f Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 21 Jul 2015 01:15:32 +0200 Subject: Switch payload encryption to AES-GCM This also ensures that the IV is generated with proper randomness. --- .../crypto/axolotl/AxolotlService.java | 28 +++++++++++++++++----- .../crypto/axolotl/CryptoFailedException.java | 7 ++++++ .../crypto/axolotl/XmppAxolotlMessage.java | 28 +++++++++++++--------- 3 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/crypto/axolotl/CryptoFailedException.java (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index b07245936..fbea3b0f2 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -4,6 +4,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.Log; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.whispersystems.libaxolotl.AxolotlAddress; import org.whispersystems.libaxolotl.DuplicateMessageException; import org.whispersystems.libaxolotl.IdentityKey; @@ -30,6 +31,7 @@ import org.whispersystems.libaxolotl.state.SessionRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import org.whispersystems.libaxolotl.util.KeyHelper; +import java.security.Security; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -678,6 +680,9 @@ public class AxolotlService { } public AxolotlService(Account account, XmppConnectionService connectionService) { + if (Security.getProvider("BC") == null) { + Security.addProvider(new BouncyCastleProvider()); + } this.mXmppConnectionService = connectionService; this.account = account; this.axolotlStore = new SQLiteAxolotlStore(this.account, this.mXmppConnectionService); @@ -1050,11 +1055,17 @@ public class AxolotlService { final String content; if (message.hasFileOnRemoteHost()) { content = message.getFileParams().url.toString(); - } else { - content = message.getBody(); - } - final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(message.getContact().getJid().toBareJid(), - getOwnDeviceId(), content); + } else { + content = message.getBody(); + } + final XmppAxolotlMessage axolotlMessage; + try { + axolotlMessage = new XmppAxolotlMessage(message.getContact().getJid().toBareJid(), + getOwnDeviceId(), content); + } catch (CryptoFailedException e) { + Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage()); + return null; + } if(findSessionsforContact(message.getContact()).isEmpty()) { return null; @@ -1143,7 +1154,12 @@ public class AxolotlService { byte[] payloadKey = session.processReceiving(header); if (payloadKey != null) { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Got payload key from axolotl header. Decrypting message..."); - plaintextMessage = message.decrypt(session, payloadKey, session.getFingerprint()); + try{ + plaintextMessage = message.decrypt(session, payloadKey, session.getFingerprint()); + } catch (CryptoFailedException e) { + Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to decrypt message: " + e.getMessage()); + break; + } } Integer preKeyId = session.getPreKeyId(); if (preKeyId != null) { diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/CryptoFailedException.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/CryptoFailedException.java new file mode 100644 index 000000000..5796ef30e --- /dev/null +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/CryptoFailedException.java @@ -0,0 +1,7 @@ +package eu.siacs.conversations.crypto.axolotl; + +public class CryptoFailedException extends Exception { + public CryptoFailedException(Exception e){ + super(e); + } +} diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java index ec068ec7e..24afeaeae 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java @@ -6,6 +6,8 @@ import android.util.Base64; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; import java.util.HashSet; import java.util.Set; @@ -107,26 +109,30 @@ public class XmppAxolotlMessage { } } - public XmppAxolotlMessage(Jid from, int sourceDeviceId, String plaintext) { + public XmppAxolotlMessage(Jid from, int sourceDeviceId, String plaintext) throws CryptoFailedException{ this.from = from; this.sourceDeviceId = sourceDeviceId; this.headers = new HashSet<>(); this.encrypt(plaintext); } - private void encrypt(String plaintext) { + private void encrypt(String plaintext) throws CryptoFailedException { try { KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(128); SecretKey secretKey = generator.generateKey(); - Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); - cipher.init(Cipher.ENCRYPT_MODE, secretKey); + SecureRandom random = new SecureRandom(); + this.iv = new byte[16]; + random.nextBytes(iv); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); this.innerKey = secretKey.getEncoded(); - this.iv = cipher.getIV(); this.ciphertext = cipher.doFinal(plaintext.getBytes()); } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException - | IllegalBlockSizeException | BadPaddingException e) { - + | IllegalBlockSizeException | BadPaddingException | NoSuchProviderException + | InvalidAlgorithmParameterException e) { + throw new CryptoFailedException(e); } } @@ -174,11 +180,11 @@ public class XmppAxolotlMessage { } - public XmppAxolotlPlaintextMessage decrypt(AxolotlService.XmppAxolotlSession session, byte[] key, String fingerprint) { + public XmppAxolotlPlaintextMessage decrypt(AxolotlService.XmppAxolotlSession session, byte[] key, String fingerprint) throws CryptoFailedException { XmppAxolotlPlaintextMessage plaintextMessage = null; try { - Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC"); SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(iv); @@ -189,8 +195,8 @@ public class XmppAxolotlMessage { } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException - | BadPaddingException e) { - throw new AssertionError(e); + | BadPaddingException | NoSuchProviderException e) { + throw new CryptoFailedException(e); } return plaintextMessage; } -- cgit v1.2.3 From 639ebd644ba7f6e05bfcb09ad1f616d0f433b5a6 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 21 Jul 2015 01:17:29 +0200 Subject: Remove unused import --- src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index fbea3b0f2..7549e439f 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -53,7 +53,6 @@ import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.stanzas.IqPacket; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; public class AxolotlService { -- cgit v1.2.3 From b7ff2c34614a92f3893732338f75cb0f7fe77d32 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 21 Jul 2015 01:52:22 +0200 Subject: Use properly fixed numeral values in Trust enum Why, oh God, why?! #thanksjamesgosling --- .../crypto/axolotl/AxolotlService.java | 30 +++++++++++++++++++--- .../conversations/persistance/DatabaseBackend.java | 10 ++++---- 2 files changed, 31 insertions(+), 9 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 7549e439f..fc1e13fd2 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -99,10 +99,28 @@ public class AxolotlService { private int currentPreKeyId = 0; public enum Trust { - UNDECIDED, // 0 - TRUSTED, - UNTRUSTED, - COMPROMISED; + UNDECIDED(0), + TRUSTED(1), + UNTRUSTED(2), + COMPROMISED(3); + + private static final Map trustsByValue = new HashMap<>(); + + static { + for (Trust trust : Trust.values()) { + trustsByValue.put(trust.getCode(), trust); + } + } + + private final int code; + + Trust(int code){ + this.code = code; + } + + public int getCode() { + return this.code; + } public String toString() { switch(this){ @@ -119,6 +137,10 @@ public class AxolotlService { public static Trust fromBoolean(Boolean trusted) { return trusted?TRUSTED:UNTRUSTED; } + + public static Trust fromCode(int code) { + return trustsByValue.get(code); + } }; private static IdentityKeyPair generateIdentityKeyPair() { diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 6091b352e..3120c0085 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -845,7 +845,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { while(cursor.moveToNext()) { if ( trust != null && cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)) - != trust.ordinal()) { + != trust.getCode()) { continue; } try { @@ -864,7 +864,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = { account.getUuid(), name, - String.valueOf(AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED.ordinal()) + String.valueOf(AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED.getCode()) }; return DatabaseUtils.queryNumEntries(db, AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?" @@ -886,7 +886,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { values.put(AxolotlService.SQLiteAxolotlStore.OWN, own ? 1 : 0); values.put(AxolotlService.SQLiteAxolotlStore.FINGERPRINT, fingerprint); values.put(AxolotlService.SQLiteAxolotlStore.KEY, base64Serialized); - values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted.ordinal()); + values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted.getCode()); db.insert(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); } @@ -896,7 +896,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (cursor.getCount() > 0) { cursor.moveToFirst(); int trustValue = cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)); - trust = AxolotlService.SQLiteAxolotlStore.Trust.values()[trustValue]; + trust = AxolotlService.SQLiteAxolotlStore.Trust.fromCode(trustValue); } cursor.close(); return trust; @@ -909,7 +909,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { fingerprint }; ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.ordinal()); + values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.getCode()); int rows = db.update(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ", -- cgit v1.2.3 From f74ee765a2cb54b163140ca482c710af0f68b101 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Jul 2015 11:46:51 +0200 Subject: bugfix: changed condition of onOtrSessionEstablished being called fixed #1263 fixed #1260 fixed #1293 --- .../java/eu/siacs/conversations/parser/MessageParser.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 38e0f98af..0d0dce49a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -70,18 +70,18 @@ public class MessageParser extends AbstractParser implements try { conversation.setLastReceivedOtrMessageId(id); Session otrSession = conversation.getOtrSession(); - SessionStatus before = otrSession.getSessionStatus(); body = otrSession.transformReceiving(body); - SessionStatus after = otrSession.getSessionStatus(); - if ((before != after) && (after == SessionStatus.ENCRYPTED)) { + SessionStatus status = otrSession.getSessionStatus(); + if (body == null && status == SessionStatus.ENCRYPTED) { conversation.setNextEncryption(Message.ENCRYPTION_OTR); mXmppConnectionService.onOtrSessionEstablished(conversation); - } else if ((before != after) && (after == SessionStatus.FINISHED)) { + return null; + } else if (body == null && status == SessionStatus.FINISHED) { conversation.setNextEncryption(Message.ENCRYPTION_NONE); conversation.resetOtrSession(); mXmppConnectionService.updateConversationUi(); - } - if ((body == null) || (body.isEmpty())) { + return null; + } else if (body == null || (body.isEmpty())) { return null; } if (body.startsWith(CryptoHelper.FILETRANSFER)) { -- cgit v1.2.3 From a5027104fdc3e64bf40a5764a2cf2bbd27a4ba99 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Jul 2015 11:50:21 +0200 Subject: bugfix: also add no-permanent-storage to message hints --- src/main/java/eu/siacs/conversations/crypto/OtrService.java | 2 +- src/main/java/eu/siacs/conversations/generator/MessageGenerator.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrService.java b/src/main/java/eu/siacs/conversations/crypto/OtrService.java index f81c9865b..45bdeb2e3 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrService.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrService.java @@ -182,7 +182,7 @@ public class OtrService extends OtrCryptoEngineImpl implements OtrEngineHost { packet.addChild("private", "urn:xmpp:carbons:2"); packet.addChild("no-copy", "urn:xmpp:hints"); packet.addChild("no-permanent-store", "urn:xmpp:hints"); - + packet.addChild("no-permanent-store", "urn:xmpp:hints"); try { Jid jid = Jid.fromSessionID(session); Conversation conversation = mXmppConnectionService.find(account,jid); diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index fed92a27c..040bc48b0 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -80,6 +80,7 @@ public class MessageGenerator extends AbstractGenerator { packet.addChild("private", "urn:xmpp:carbons:2"); packet.addChild("no-copy", "urn:xmpp:hints"); packet.addChild("no-permanent-store", "urn:xmpp:hints"); + packet.addChild("no-permanent-storage", "urn:xmpp:hints"); try { String content; if (message.hasFileOnRemoteHost()) { -- cgit v1.2.3 From 87bc9d3a31a7f92b13293669c4c5ce2c5a02f6ae Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Jul 2015 11:52:49 +0200 Subject: end otr session when receiving failed otr message warnings --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 0d0dce49a..b81a62da6 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -202,7 +202,13 @@ public class MessageParser extends AbstractParser implements if (packet.getType() == MessagePacket.TYPE_ERROR) { Jid from = packet.getFrom(); if (from != null) { - mXmppConnectionService.markMessage(account, from.toBareJid(), packet.getId(), Message.STATUS_SEND_FAILED); + Message message = mXmppConnectionService.markMessage(account, + from.toBareJid(), + packet.getId(), + Message.STATUS_SEND_FAILED); + if (message.getEncryption() == Message.ENCRYPTION_OTR) { + message.getConversation().endOtrIfNeeded(); + } } return true; } -- cgit v1.2.3 From ffa588ba3e40041b44e2ac18efc812df0a11b63d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Jul 2015 12:01:20 +0200 Subject: and now do that properly --- src/main/java/eu/siacs/conversations/crypto/OtrService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/OtrService.java b/src/main/java/eu/siacs/conversations/crypto/OtrService.java index 45bdeb2e3..1b296cc4e 100644 --- a/src/main/java/eu/siacs/conversations/crypto/OtrService.java +++ b/src/main/java/eu/siacs/conversations/crypto/OtrService.java @@ -182,7 +182,7 @@ public class OtrService extends OtrCryptoEngineImpl implements OtrEngineHost { packet.addChild("private", "urn:xmpp:carbons:2"); packet.addChild("no-copy", "urn:xmpp:hints"); packet.addChild("no-permanent-store", "urn:xmpp:hints"); - packet.addChild("no-permanent-store", "urn:xmpp:hints"); + packet.addChild("no-permanent-storage", "urn:xmpp:hints"); try { Jid jid = Jid.fromSessionID(session); Conversation conversation = mXmppConnectionService.find(account,jid); -- cgit v1.2.3 From 1aeb5874b042b7461e82dddbb34f70c5149a789f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Jul 2015 13:15:59 +0200 Subject: allow for private messages being started from muc details in anonymous mucs --- .../ui/ConferenceDetailsActivity.java | 22 +++++++++++++++------- .../conversations/ui/ConversationActivity.java | 22 ++++++++++++++++++---- .../eu/siacs/conversations/ui/XmppActivity.java | 13 +++++++++---- 3 files changed, 42 insertions(+), 15 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 475bc4230..947779316 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -265,14 +265,16 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers final User self = mConversation.getMucOptions().getSelf(); this.mSelectedUser = user; String name; + final Contact contact = user.getContact(); + if (contact != null) { + name = contact.getDisplayName(); + } else if (user.getJid() != null){ + name = user.getJid().toBareJid().toString(); + } else { + name = user.getName(); + } + menu.setHeaderTitle(name); if (user.getJid() != null) { - final Contact contact = user.getContact(); - if (contact != null) { - name = contact.getDisplayName(); - } else { - name = user.getJid().toBareJid().toString(); - } - menu.setHeaderTitle(name); MenuItem showContactDetails = menu.findItem(R.id.action_contact_details); MenuItem startConversation = menu.findItem(R.id.start_conversation); MenuItem giveMembership = menu.findItem(R.id.give_membership); @@ -303,6 +305,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers removeAdminPrivileges.setVisible(true); } } + } else { + MenuItem sendPrivateMessage = menu.findItem(R.id.send_private_message); + sendPrivateMessage.setVisible(true); } } @@ -340,6 +345,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers xmppConnectionService.changeAffiliationInConference(mConversation,mSelectedUser.getJid(), MucOptions.Affiliation.OUTCAST,this); xmppConnectionService.changeRoleInConference(mConversation,mSelectedUser.getName(), MucOptions.Role.NONE,this); return true; + case R.id.send_private_message: + privateMsgInMuc(mConversation,mSelectedUser.getName()); + return true; default: return super.onContextItemSelected(item); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 1a643b7e3..92b8e5443 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -51,6 +51,8 @@ import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.ui.adapter.ConversationAdapter; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; +import eu.siacs.conversations.xmpp.jid.Jid; public class ConversationActivity extends XmppActivity implements OnAccountUpdate, OnConversationUpdate, OnRosterUpdate, OnUpdateBlocklist, XmppConnectionService.OnShowErrorToast { @@ -62,6 +64,7 @@ public class ConversationActivity extends XmppActivity public static final String MESSAGE = "messageUuid"; public static final String TEXT = "text"; public static final String NICK = "nick"; + public static final String PRIVATE_MESSAGE = "pm"; public static final int REQUEST_SEND_MESSAGE = 0x0201; public static final int REQUEST_DECRYPT_PGP = 0x0202; @@ -464,7 +467,7 @@ public class ConversationActivity extends XmppActivity conversation.setNextCounterpart(null); callback.onPresenceSelected(); } else { - selectPresence(conversation,callback); + selectPresence(conversation, callback); } } @@ -474,7 +477,7 @@ public class ConversationActivity extends XmppActivity if (intent.resolveActivity(getPackageManager()) != null) { return intent; } else { - intent.setData(Uri.parse("http://play.google.com/store/apps/details?id="+packageId)); + intent.setData(Uri.parse("http://play.google.com/store/apps/details?id=" + packageId)); return intent; } } @@ -831,7 +834,7 @@ public class ConversationActivity extends XmppActivity } conversation.setMutedTill(till); ConversationActivity.this.xmppConnectionService.databaseBackend - .updateConversation(conversation); + .updateConversation(conversation); updateConversationList(); ConversationActivity.this.mConversationFragment.updateMessages(); invalidateOptionsMenu(); @@ -995,10 +998,21 @@ public class ConversationActivity extends XmppActivity final String downloadUuid = intent.getStringExtra(MESSAGE); final String text = intent.getStringExtra(TEXT); final String nick = intent.getStringExtra(NICK); + final boolean pm = intent.getBooleanExtra(PRIVATE_MESSAGE,false); if (selectConversationByUuid(uuid)) { this.mConversationFragment.reInit(getSelectedConversation()); if (nick != null) { - this.mConversationFragment.highlightInConference(nick); + if (pm) { + Jid jid = getSelectedConversation().getJid(); + try { + Jid next = Jid.fromParts(jid.getLocalpart(),jid.getDomainpart(),nick); + this.mConversationFragment.privateMessageWith(next); + } catch (final InvalidJidException ignored) { + //do nothing + } + } else { + this.mConversationFragment.highlightInConference(nick); + } } else { this.mConversationFragment.appendText(text); } diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 197836278..a0a8d520d 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -384,14 +384,18 @@ public abstract class XmppActivity extends Activity { public void switchToConversation(Conversation conversation, String text, boolean newTask) { - switchToConversation(conversation,text,null,newTask); + switchToConversation(conversation,text,null,false,newTask); } public void highlightInMuc(Conversation conversation, String nick) { - switchToConversation(conversation, null, nick, false); + switchToConversation(conversation, null, nick, false, false); } - private void switchToConversation(Conversation conversation, String text, String nick, boolean newTask) { + public void privateMsgInMuc(Conversation conversation, String nick) { + switchToConversation(conversation, null, nick, true, false); + } + + private void switchToConversation(Conversation conversation, String text, String nick, boolean pm, boolean newTask) { Intent viewConversationIntent = new Intent(this, ConversationActivity.class); viewConversationIntent.setAction(Intent.ACTION_VIEW); @@ -402,6 +406,7 @@ public abstract class XmppActivity extends Activity { } if (nick != null) { viewConversationIntent.putExtra(ConversationActivity.NICK, nick); + viewConversationIntent.putExtra(ConversationActivity.PRIVATE_MESSAGE,pm); } viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); if (newTask) { @@ -456,7 +461,7 @@ public abstract class XmppActivity extends Activity { @Override public void userInputRequried(PendingIntent pi, - Account account) { + Account account) { try { startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0); -- cgit v1.2.3 From 3c5c0c7d3b4ceaaca51b64ca91d2d1fcd76f9a66 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 21 Jul 2015 13:51:15 +0200 Subject: Fill own device sessions into SessionMap --- .../crypto/axolotl/AxolotlService.java | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index fc1e13fd2..a004599d6 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -662,21 +662,28 @@ public class AxolotlService { this.fillMap(store); } + private void putDevicesForJid(String bareJid, List deviceIds, SQLiteAxolotlStore store) { + for (Integer deviceId : deviceIds) { + AxolotlAddress axolotlAddress = new AxolotlAddress(bareJid, deviceId); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Building session for remote address: "+axolotlAddress.toString()); + String fingerprint = store.loadSession(axolotlAddress).getSessionState().getRemoteIdentityKey().getFingerprint().replaceAll("\\s", ""); + this.put(axolotlAddress, new XmppAxolotlSession(account, store, axolotlAddress, fingerprint)); + } + } + private void fillMap(SQLiteAxolotlStore store) { + List deviceIds = store.getSubDeviceSessions(account.getJid().toBareJid().toString()); + putDevicesForJid(account.getJid().toBareJid().toString(), deviceIds, store); for (Contact contact : account.getRoster().getContacts()) { Jid bareJid = contact.getJid().toBareJid(); if (bareJid == null) { continue; // FIXME: handle this? } String address = bareJid.toString(); - List deviceIDs = store.getSubDeviceSessions(address); - for (Integer deviceId : deviceIDs) { - AxolotlAddress axolotlAddress = new AxolotlAddress(address, deviceId); - Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Building session for remote address: "+axolotlAddress.toString()); - String fingerprint = store.loadSession(axolotlAddress).getSessionState().getRemoteIdentityKey().getFingerprint().replaceAll("\\s", ""); - this.put(axolotlAddress, new XmppAxolotlSession(account, store, axolotlAddress, fingerprint)); - } + deviceIds = store.getSubDeviceSessions(address); + putDevicesForJid(address, deviceIds, store); } + } @Override -- cgit v1.2.3 From 92b5081b5ebac1a3108a821a270beb3f7d9c39ee Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 21 Jul 2015 14:18:16 +0200 Subject: Add INACTIVE state for removed keys We introduce a new trust state: INACTIVE. This state is intended for old keys that have been removed. When a TRUSTED device is removed from the PEP devicelist, it's status will be set to INACTIVE. INACTIVE keys are shown in the UI as greyed out, non-interactible key rows. Messages are not encrypted for INACTIVE devices. When an INACTIVE device reappears in PEP, or a message is received from an INACTIVE device, it is set back to trusted. --- .../crypto/axolotl/AxolotlService.java | 54 +++++++++++++++++----- .../services/XmppConnectionService.java | 31 +++++++------ .../conversations/ui/ContactDetailsActivity.java | 8 +++- .../conversations/ui/EditAccountActivity.java | 8 +++- .../siacs/conversations/ui/TrustKeysActivity.java | 6 +-- .../eu/siacs/conversations/ui/XmppActivity.java | 24 ++++++++-- .../conversations/xmpp/OnKeyStatusUpdated.java | 5 ++ .../conversations/xmpp/OnNewKeysAvailable.java | 5 -- 8 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnKeyStatusUpdated.java delete mode 100644 src/main/java/eu/siacs/conversations/xmpp/OnNewKeysAvailable.java (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index a004599d6..c30a7ab86 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -102,7 +102,8 @@ public class AxolotlService { UNDECIDED(0), TRUSTED(1), UNTRUSTED(2), - COMPROMISED(3); + COMPROMISED(3), + INACTIVE(4); private static final Map trustsByValue = new HashMap<>(); @@ -125,12 +126,16 @@ public class AxolotlService { public String toString() { switch(this){ case UNDECIDED: - return "Trust undecided"; + return "Trust undecided "+getCode(); case TRUSTED: - return "Trusted"; + return "Trusted "+getCode(); + case COMPROMISED: + return "Compromised "+getCode(); + case INACTIVE: + return "Inactive "+getCode(); case UNTRUSTED: default: - return "Untrusted"; + return "Untrusted "+getCode(); } } @@ -538,14 +543,20 @@ public class AxolotlService { return fingerprint; } - private SQLiteAxolotlStore.Trust getTrust() { + protected void setTrust(SQLiteAxolotlStore.Trust trust) { + sqLiteAxolotlStore.setFingerprintTrust(fingerprint, trust); + } + + protected SQLiteAxolotlStore.Trust getTrust() { return sqLiteAxolotlStore.getFingerprintTrust(fingerprint); } @Nullable public byte[] processReceiving(XmppAxolotlMessage.XmppAxolotlMessageHeader incomingHeader) { byte[] plaintext = null; - switch (getTrust()) { + SQLiteAxolotlStore.Trust trust = getTrust(); + switch (trust) { + case INACTIVE: case UNDECIDED: case UNTRUSTED: case TRUSTED: @@ -574,6 +585,10 @@ public class AxolotlService { Log.w(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Error decrypting axolotl header, "+e.getClass().getName()+": " + e.getMessage()); } + if (plaintext != null && trust == SQLiteAxolotlStore.Trust.INACTIVE) { + setTrust(SQLiteAxolotlStore.Trust.TRUSTED); + } + break; case COMPROMISED: @@ -774,15 +789,32 @@ public class AxolotlService { return this.deviceIds.get(account.getJid().toBareJid()); } + private void setTrustOnSessions(final Jid jid, @NonNull final Set deviceIds, + final SQLiteAxolotlStore.Trust from, + final SQLiteAxolotlStore.Trust to) { + for(Integer deviceId:deviceIds) { + AxolotlAddress address = new AxolotlAddress(jid.toBareJid().toString(), deviceId); + XmppAxolotlSession session = sessions.get(address); + if (session != null && session.getFingerprint() != null + && session.getTrust() == from) { + session.setTrust(to); + } + } + } + public void registerDevices(final Jid jid, @NonNull final Set deviceIds) { if(deviceIds.contains(getOwnDeviceId())) { - Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Skipping own Device ID:"+ jid + ":"+getOwnDeviceId()); deviceIds.remove(getOwnDeviceId()); } - for(Integer i:deviceIds) { - Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Adding Device ID:"+ jid + ":"+i); - } + Set expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toString())); + expiredDevices.removeAll(deviceIds); + setTrustOnSessions(jid, expiredDevices, SQLiteAxolotlStore.Trust.TRUSTED, + SQLiteAxolotlStore.Trust.INACTIVE); + Set newDevices = new HashSet<>(deviceIds); + setTrustOnSessions(jid, newDevices, SQLiteAxolotlStore.Trust.INACTIVE, + SQLiteAxolotlStore.Trust.TRUSTED); this.deviceIds.put(jid, deviceIds); + mXmppConnectionService.keyStatusUpdated(); publishOwnDeviceIdIfNeeded(); } @@ -957,7 +989,7 @@ public class AxolotlService { } }); } - mXmppConnectionService.newKeysAvailable(); + mXmppConnectionService.keyStatusUpdated(); } } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index e7df9e6a9..fa0a87096 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -86,7 +86,7 @@ import eu.siacs.conversations.xmpp.OnContactStatusChanged; import eu.siacs.conversations.xmpp.OnIqPacketReceived; import eu.siacs.conversations.xmpp.OnMessageAcknowledged; import eu.siacs.conversations.xmpp.OnMessagePacketReceived; -import eu.siacs.conversations.xmpp.OnNewKeysAvailable; +import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnPresencePacketReceived; import eu.siacs.conversations.xmpp.OnStatusChanged; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; @@ -309,8 +309,8 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa private int rosterChangedListenerCount = 0; private OnMucRosterUpdate mOnMucRosterUpdate = null; private int mucRosterChangedListenerCount = 0; - private OnNewKeysAvailable mOnNewKeysAvailable = null; - private int newKeysAvailableListenerCount = 0; + private OnKeyStatusUpdated mOnKeyStatusUpdated = null; + private int keyStatusUpdatedListenerCount = 0; private SecureRandom mRandom; private OpenPgpServiceConnection pgpServiceConnection; private PgpEngine mPgpEngine = null; @@ -1372,30 +1372,31 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - public void setOnNewKeysAvailableListener(final OnNewKeysAvailable listener) { + public void setOnKeyStatusUpdatedListener(final OnKeyStatusUpdated listener) { synchronized (this) { if (checkListeners()) { switchToForeground(); } - this.mOnNewKeysAvailable = listener; - if (this.newKeysAvailableListenerCount < 2) { - this.newKeysAvailableListenerCount++; + this.mOnKeyStatusUpdated = listener; + if (this.keyStatusUpdatedListenerCount < 2) { + this.keyStatusUpdatedListenerCount++; } } } public void removeOnNewKeysAvailableListener() { synchronized (this) { - this.newKeysAvailableListenerCount--; - if (this.newKeysAvailableListenerCount <= 0) { - this.newKeysAvailableListenerCount = 0; - this.mOnNewKeysAvailable = null; + this.keyStatusUpdatedListenerCount--; + if (this.keyStatusUpdatedListenerCount <= 0) { + this.keyStatusUpdatedListenerCount = 0; + this.mOnKeyStatusUpdated = null; if (checkListeners()) { switchToBackground(); } } } } + public void setOnMucRosterUpdateListener(OnMucRosterUpdate listener) { synchronized (this) { if (checkListeners()) { @@ -1427,7 +1428,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa && this.mOnRosterUpdate == null && this.mOnUpdateBlocklist == null && this.mOnShowErrorToast == null - && this.mOnNewKeysAvailable == null); + && this.mOnKeyStatusUpdated == null); } private void switchToForeground() { @@ -2316,9 +2317,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } - public void newKeysAvailable() { - if(mOnNewKeysAvailable != null) { - mOnNewKeysAvailable.onNewKeysAvailable(); + public void keyStatusUpdated() { + if(mOnKeyStatusUpdated != null) { + mOnKeyStatusUpdated.onKeyStatusUpdated(); } } diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 16e16cff4..a0e02c1b8 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -42,12 +42,13 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnRosterUpdate; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.XmppConnection; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; -public class ContactDetailsActivity extends XmppActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist { +public class ContactDetailsActivity extends XmppActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist, OnKeyStatusUpdated { public static final String ACTION_VIEW_CONTACT = "view_contact"; private Contact contact; @@ -468,4 +469,9 @@ public class ContactDetailsActivity extends XmppActivity implements OnAccountUpd populateView(); } } + + @Override + public void onKeyStatusUpdated() { + refreshUi(); + } } diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index ac0f66169..aac8788fc 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -35,12 +35,13 @@ import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.UIHelper; +import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.XmppConnection.Features; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import eu.siacs.conversations.xmpp.pep.Avatar; -public class EditAccountActivity extends XmppActivity implements OnAccountUpdate{ +public class EditAccountActivity extends XmppActivity implements OnAccountUpdate, OnKeyStatusUpdated { private AutoCompleteTextView mAccountJid; private EditText mPassword; @@ -618,4 +619,9 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate }); builder.create().show(); } + + @Override + public void onKeyStatusUpdated() { + refreshUi(); + } } diff --git a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java index ccdef9c39..1bf07f3ea 100644 --- a/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/TrustKeysActivity.java @@ -20,11 +20,11 @@ import eu.siacs.conversations.crypto.axolotl.AxolotlService.SQLiteAxolotlStore.T import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; -import eu.siacs.conversations.xmpp.OnNewKeysAvailable; +import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; -public class TrustKeysActivity extends XmppActivity implements OnNewKeysAvailable { +public class TrustKeysActivity extends XmppActivity implements OnKeyStatusUpdated { private Jid accountJid; private Jid contactJid; private boolean hasOtherTrustedKeys = false; @@ -215,7 +215,7 @@ public class TrustKeysActivity extends XmppActivity implements OnNewKeysAvailabl } @Override - public void onNewKeysAvailable() { + public void onKeyStatusUpdated() { final Account account = xmppConnectionService.findAccountByJid(accountJid); hasPendingFetches = false; getFingerprints(account); diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index a0a8d520d..4cb6841bc 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -83,7 +83,7 @@ import eu.siacs.conversations.services.XmppConnectionService.XmppConnectionBinde import eu.siacs.conversations.ui.widget.Switch; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.ExceptionHelper; -import eu.siacs.conversations.xmpp.OnNewKeysAvailable; +import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; @@ -99,6 +99,7 @@ public abstract class XmppActivity extends Activity { protected int mPrimaryTextColor; protected int mSecondaryTextColor; + protected int mTertiaryTextColor; protected int mPrimaryBackgroundColor; protected int mSecondaryBackgroundColor; protected int mColorRed; @@ -294,8 +295,8 @@ public abstract class XmppActivity extends Activity { if (this instanceof XmppConnectionService.OnShowErrorToast) { this.xmppConnectionService.setOnShowErrorToastListener((XmppConnectionService.OnShowErrorToast) this); } - if (this instanceof OnNewKeysAvailable) { - this.xmppConnectionService.setOnNewKeysAvailableListener((OnNewKeysAvailable) this); + if (this instanceof OnKeyStatusUpdated) { + this.xmppConnectionService.setOnKeyStatusUpdatedListener((OnKeyStatusUpdated) this); } } @@ -318,7 +319,7 @@ public abstract class XmppActivity extends Activity { if (this instanceof XmppConnectionService.OnShowErrorToast) { this.xmppConnectionService.removeOnShowErrorToastListener(); } - if (this instanceof OnNewKeysAvailable) { + if (this instanceof OnKeyStatusUpdated) { this.xmppConnectionService.removeOnNewKeysAvailableListener(); } } @@ -349,6 +350,7 @@ public abstract class XmppActivity extends Activity { ExceptionHelper.init(getApplicationContext()); mPrimaryTextColor = getResources().getColor(R.color.black87); mSecondaryTextColor = getResources().getColor(R.color.black54); + mTertiaryTextColor = getResources().getColor(R.color.black12); mColorRed = getResources().getColor(R.color.red500); mColorOrange = getResources().getColor(R.color.orange500); mColorGreen = getResources().getColor(R.color.green500); @@ -668,10 +670,20 @@ public abstract class XmppActivity extends Activity { case TRUSTED: trustToggle.setChecked(trust == AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED, false); trustToggle.setEnabled(true); + key.setTextColor(getPrimaryTextColor()); + keyType.setTextColor(getSecondaryTextColor()); break; case UNDECIDED: trustToggle.setChecked(false, false); trustToggle.setEnabled(false); + key.setTextColor(getPrimaryTextColor()); + keyType.setTextColor(getSecondaryTextColor()); + break; + case INACTIVE: + trustToggle.setChecked(true, false); + trustToggle.setEnabled(false); + key.setTextColor(getTertiaryTextColor()); + keyType.setTextColor(getTertiaryTextColor()); break; } @@ -824,6 +836,10 @@ public abstract class XmppActivity extends Activity { } }; + public int getTertiaryTextColor() { + return this.mTertiaryTextColor; + } + public int getSecondaryTextColor() { return this.mSecondaryTextColor; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/OnKeyStatusUpdated.java b/src/main/java/eu/siacs/conversations/xmpp/OnKeyStatusUpdated.java new file mode 100644 index 000000000..65ae133d5 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/xmpp/OnKeyStatusUpdated.java @@ -0,0 +1,5 @@ +package eu.siacs.conversations.xmpp; + +public interface OnKeyStatusUpdated { + public void onKeyStatusUpdated(); +} diff --git a/src/main/java/eu/siacs/conversations/xmpp/OnNewKeysAvailable.java b/src/main/java/eu/siacs/conversations/xmpp/OnNewKeysAvailable.java deleted file mode 100644 index 59dc1c1ea..000000000 --- a/src/main/java/eu/siacs/conversations/xmpp/OnNewKeysAvailable.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.siacs.conversations.xmpp; - -public interface OnNewKeysAvailable { - public void onNewKeysAvailable(); -} -- cgit v1.2.3 From f6281a182df6e251a326538702bf4f3b6f80a62b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Jul 2015 19:44:25 +0200 Subject: fixed npe in error message handling --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index b81a62da6..c2fdf5b8a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -206,7 +206,7 @@ public class MessageParser extends AbstractParser implements from.toBareJid(), packet.getId(), Message.STATUS_SEND_FAILED); - if (message.getEncryption() == Message.ENCRYPTION_OTR) { + if (message != null && message.getEncryption() == Message.ENCRYPTION_OTR) { message.getConversation().endOtrIfNeeded(); } } -- cgit v1.2.3 From 456d4c8b23dcf968322841c99d80c79ccda6571b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Jul 2015 23:49:35 +0200 Subject: made image file format configurable by Config.java --- src/main/java/eu/siacs/conversations/Config.java | 4 ++++ .../conversations/generator/MessageGenerator.java | 4 ---- .../siacs/conversations/persistance/FileBackend.java | 18 ++++++++++++++---- 3 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 0f4b34047..b697e7fec 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -19,6 +19,10 @@ public final class Config { public static final int AVATAR_SIZE = 192; public static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.WEBP; + public static final int IMAGE_SIZE = 1920; + public static final Bitmap.CompressFormat IMAGE_FORMAT = Bitmap.CompressFormat.WEBP; + public static final int IMAGE_QUALITY = 75; + public static final int MESSAGE_MERGE_WINDOW = 20; public static final int PAGE_SIZE = 50; diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 040bc48b0..bfa1dc850 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -1,7 +1,5 @@ package eu.siacs.conversations.generator; -import android.util.Log; - import net.java.otr4j.OtrException; import net.java.otr4j.session.Session; @@ -10,8 +8,6 @@ import java.util.Date; import java.util.Locale; import java.util.TimeZone; -import eu.siacs.conversations.Config; -import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index d607345e3..13bbb2769 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -184,8 +184,18 @@ public class FileBackend { return this.copyImageToPrivateStorage(message, image, 0); } - private DownloadableFile copyImageToPrivateStorage(Message message, - Uri image, int sampleSize) throws FileCopyException { + private DownloadableFile copyImageToPrivateStorage(Message message,Uri image, int sampleSize) throws FileCopyException { + switch(Config.IMAGE_FORMAT) { + case JPEG: + message.setRelativeFilePath(message.getUuid()+".jpg"); + break; + case PNG: + message.setRelativeFilePath(message.getUuid()+".png"); + break; + case WEBP: + message.setRelativeFilePath(message.getUuid()+".webp"); + break; + } DownloadableFile file = getFile(message); file.getParentFile().mkdirs(); InputStream is = null; @@ -205,13 +215,13 @@ public class FileBackend { if (originalBitmap == null) { throw new FileCopyException(R.string.error_not_an_image_file); } - Bitmap scaledBitmap = resize(originalBitmap, IMAGE_SIZE); + Bitmap scaledBitmap = resize(originalBitmap, Config.IMAGE_SIZE); int rotation = getRotation(image); if (rotation > 0) { scaledBitmap = rotate(scaledBitmap, rotation); } - boolean success = scaledBitmap.compress(Bitmap.CompressFormat.WEBP, 75, os); + boolean success = scaledBitmap.compress(Config.IMAGE_FORMAT, Config.IMAGE_QUALITY, os); if (!success) { throw new FileCopyException(R.string.error_compressing_image); } -- cgit v1.2.3 From 4c1c2892c772fa4622195c81ad35c9e51ab02f35 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 22 Jul 2015 00:53:18 +0200 Subject: Disable trust toggle completely for INACTIVE keys --- src/main/java/eu/siacs/conversations/ui/XmppActivity.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 4cb6841bc..835685107 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -680,6 +680,7 @@ public abstract class XmppActivity extends Activity { keyType.setTextColor(getSecondaryTextColor()); break; case INACTIVE: + trustToggle.setOnClickListener(null); trustToggle.setChecked(true, false); trustToggle.setEnabled(false); key.setTextColor(getTertiaryTextColor()); -- cgit v1.2.3 From c2813cea290b59036bf6d162552e6df3b715ab81 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 22 Jul 2015 01:00:20 +0200 Subject: Hide regenerate keys button Can re-enable it via Config.java setting --- src/main/java/eu/siacs/conversations/Config.java | 2 ++ .../conversations/ui/EditAccountActivity.java | 23 ++++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index b697e7fec..d79a12f22 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -37,6 +37,8 @@ public final class Config { public static final boolean ENCRYPT_ON_HTTP_UPLOADED = false; + public static final boolean SHOW_REGENERATE_AXOLOTL_KEYS_BUTTON = false; + public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2; public static final int MAM_MAX_MESSAGES = 500; diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index aac8788fc..3c1f155df 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -29,6 +29,7 @@ import org.whispersystems.libaxolotl.IdentityKey; import java.util.Set; +import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; @@ -547,16 +548,18 @@ public class EditAccountActivity extends XmppActivity implements OnAccountUpdate } } }); - this.mRegenerateAxolotlKeyButton - .setVisibility(View.VISIBLE); - this.mRegenerateAxolotlKeyButton - .setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(final View v) { - showRegenerateAxolotlKeyDialog(); - } - }); + if (Config.SHOW_REGENERATE_AXOLOTL_KEYS_BUTTON) { + this.mRegenerateAxolotlKeyButton + .setVisibility(View.VISIBLE); + this.mRegenerateAxolotlKeyButton + .setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(final View v) { + showRegenerateAxolotlKeyDialog(); + } + }); + } } else { this.mAxolotlFingerprintBox.setVisibility(View.GONE); } -- cgit v1.2.3 From a1e63944a20d88edc71049424538d61df4b7de9a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jul 2015 12:15:09 +0200 Subject: use 'interactive mode' when starting downloads from the context menu --- src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java | 1 - src/main/java/eu/siacs/conversations/ui/ConversationFragment.java | 2 +- src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index d7487af9d..30d9a393a 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -35,7 +35,6 @@ public class HttpDownloadConnection implements Transferable { private int mStatus = Transferable.STATUS_UNKNOWN; private boolean acceptedAutomatically = false; private int mProgress = 0; - private long mLastGuiRefresh = 0; public HttpDownloadConnection(HttpConnectionManager manager) { this.mHttpConnectionManager = manager; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index f40b06c83..f9144083a 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -571,7 +571,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private void downloadFile(Message message) { activity.xmppConnectionService.getHttpConnectionManager() - .createNewDownloadConnection(message); + .createNewDownloadConnection(message,true); } private void cancelTransmission(Message message) { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 679fb3558..b158f0fe4 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -573,7 +573,7 @@ public class MessageAdapter extends ArrayAdapter { Toast.LENGTH_SHORT).show(); } } else if (message.treatAsDownloadable() != Message.Decision.NEVER) { - activity.xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message); + activity.xmppConnectionService.getHttpConnectionManager().createNewDownloadConnection(message,true); } } -- cgit v1.2.3 From 63206e6d4a0713719ff19cb38c93d091fe0c4735 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jul 2015 14:15:00 +0200 Subject: use type=chat more often to go along with new, simple carbon and mam rules * change chat states to type=chat and chat markers to type=chat * use same type as requesting stanza for delivery receipts (which should make them type=chat most of the time) --- .../siacs/conversations/generator/MessageGenerator.java | 11 +++++------ .../eu/siacs/conversations/parser/MessageParser.java | 16 ++++++++++------ 2 files changed, 15 insertions(+), 12 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index bfa1dc850..484fca001 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -115,6 +115,7 @@ public class MessageGenerator extends AbstractGenerator { public MessagePacket generateChatState(Conversation conversation) { final Account account = conversation.getAccount(); MessagePacket packet = new MessagePacket(); + packet.setType(MessagePacket.TYPE_CHAT); packet.setTo(conversation.getJid().toBareJid()); packet.setFrom(account.getJid()); packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); @@ -123,7 +124,7 @@ public class MessageGenerator extends AbstractGenerator { public MessagePacket confirm(final Account account, final Jid to, final String id) { MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_NORMAL); + packet.setType(MessagePacket.TYPE_CHAT); packet.setTo(to); packet.setFrom(account.getJid()); Element received = packet.addChild("displayed","urn:xmpp:chat-markers:0"); @@ -131,8 +132,7 @@ public class MessageGenerator extends AbstractGenerator { return packet; } - public MessagePacket conferenceSubject(Conversation conversation, - String subject) { + public MessagePacket conferenceSubject(Conversation conversation,String subject) { MessagePacket packet = new MessagePacket(); packet.setType(MessagePacket.TYPE_GROUPCHAT); packet.setTo(conversation.getJid().toBareJid()); @@ -166,10 +166,9 @@ public class MessageGenerator extends AbstractGenerator { return packet; } - public MessagePacket received(Account account, - MessagePacket originalMessage, String namespace) { + public MessagePacket received(Account account, MessagePacket originalMessage, String namespace, int type) { MessagePacket receivedPacket = new MessagePacket(); - receivedPacket.setType(MessagePacket.TYPE_NORMAL); + receivedPacket.setType(type); receivedPacket.setTo(originalMessage.getFrom()); receivedPacket.setFrom(account.getJid()); Element received = receivedPacket.addChild("received", namespace); diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index c2fdf5b8a..6e7b3276d 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -263,7 +263,7 @@ public class MessageParser extends AbstractParser implements timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis()); } final String body = packet.getBody(); - final Element mucUserElement = packet.findChild("x","http://jabber.org/protocol/muc#user"); + final Element mucUserElement = packet.findChild("x", "http://jabber.org/protocol/muc#user"); final String pgpEncrypted = packet.findChildContent("x", "jabber:x:encrypted"); final Element axolotlEncrypted = packet.findChild("axolotl_message", AxolotlService.PEP_PREFIX); int status; @@ -369,15 +369,19 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.updateConversationUi(); } - if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded) { + if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded && !isTypeGroupChat) { if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, "urn:xmpp:chat-markers:0"); + MessagePacket receipt = mXmppConnectionService.getMessageGenerator().received(account, + packet, + "urn:xmpp:chat-markers:0", + MessagePacket.TYPE_CHAT); mXmppConnectionService.sendMessagePacket(account, receipt); } if (packet.hasChild("request", "urn:xmpp:receipts")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, "urn:xmpp:receipts"); + MessagePacket receipt = mXmppConnectionService.getMessageGenerator().received(account, + packet, + "urn:xmpp:receipts", + packet.getType()); mXmppConnectionService.sendMessagePacket(account, receipt); } } -- cgit v1.2.3 From 9c1c86ed444cfa860b6e958849dd6a55b9a16a04 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jul 2015 14:17:02 +0200 Subject: add no-store to chat states --- src/main/java/eu/siacs/conversations/generator/MessageGenerator.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 484fca001..045916725 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -119,6 +119,8 @@ public class MessageGenerator extends AbstractGenerator { packet.setTo(conversation.getJid().toBareJid()); packet.setFrom(account.getJid()); packet.addChild(ChatState.toElement(conversation.getOutgoingChatState())); + packet.addChild("no-store", "urn:xmpp:hints"); + packet.addChild("no-storage", "urn:xmpp:hints"); //wrong! don't copy this. Its *store* return packet; } -- cgit v1.2.3 From db05d264334b548ce2f307d614e39aabd775bb4f Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 22 Jul 2015 15:02:53 +0200 Subject: Always build own device session automatically --- .../conversations/crypto/axolotl/AxolotlService.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index c30a7ab86..c6f74538a 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -803,8 +803,16 @@ public class AxolotlService { } public void registerDevices(final Jid jid, @NonNull final Set deviceIds) { - if(deviceIds.contains(getOwnDeviceId())) { - deviceIds.remove(getOwnDeviceId()); + if(jid.toBareJid().equals(account.getJid().toBareJid())) { + if (deviceIds.contains(getOwnDeviceId())) { + deviceIds.remove(getOwnDeviceId()); + } + for(Integer deviceId : deviceIds) { + AxolotlAddress ownDeviceAddress = new AxolotlAddress(jid.toBareJid().toString(),deviceId); + if(sessions.get(ownDeviceAddress) == null) { + buildSessionFromPEP(null, ownDeviceAddress, false); + } + } } Set expiredDevices = new HashSet<>(axolotlStore.getSubDeviceSessions(jid.toBareJid().toString())); expiredDevices.removeAll(deviceIds); @@ -976,11 +984,10 @@ public class AxolotlService { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Retrieving bundle: " + bundlesPacket); mXmppConnectionService.sendIqPacket(account, bundlesPacket, new OnIqPacketReceived() { private void finish() { - AxolotlAddress ownAddress = new AxolotlAddress(conversation.getAccount().getJid().toBareJid().toString(),0); - AxolotlAddress foreignAddress = new AxolotlAddress(conversation.getJid().toBareJid().toString(),0); + AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(),0); if (!fetchStatusMap.getAll(ownAddress).containsValue(FetchStatus.PENDING) - && !fetchStatusMap.getAll(foreignAddress).containsValue(FetchStatus.PENDING)) { - if (flushWaitingQueueAfterFetch) { + && !fetchStatusMap.getAll(address).containsValue(FetchStatus.PENDING)) { + if (flushWaitingQueueAfterFetch && conversation != null) { conversation.findUnsentMessagesWithEncryption(Message.ENCRYPTION_AXOLOTL, new Conversation.OnMessageFound() { @Override -- cgit v1.2.3 From f7634a85be516feef753bdb32fed8df7da1573ed Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jul 2015 15:31:00 +0200 Subject: treat private, non-anonymous mucs like 1:1 chats notification wise --- src/main/java/eu/siacs/conversations/entities/Conversation.java | 7 +++++++ .../java/eu/siacs/conversations/services/NotificationService.java | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 2efd8a290..6d99e3588 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -519,6 +519,13 @@ public class Conversation extends AbstractEntity implements Blockable { return getContact().getOtrFingerprints().contains(getOtrFingerprint()); } + /** + * short for is Private and Non-anonymous + */ + public boolean isPnNA() { + return mode == MODE_SINGLE || (getMucOptions().membersOnly() && getMucOptions().nonanonymous()); + } + public synchronized MucOptions getMucOptions() { if (this.mucOptions == null) { this.mucOptions = new MucOptions(this); diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 956f704eb..47f0347fa 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -64,7 +64,7 @@ public class NotificationService { return (message.getStatus() == Message.STATUS_RECEIVED) && notificationsEnabled() && !message.getConversation().isMuted() - && (message.getConversation().getMode() == Conversation.MODE_SINGLE + && (message.getConversation().isPnNA() || conferenceNotificationsEnabled() || wasHighlightedOrPrivate(message) ); -- cgit v1.2.3 From cd204d5931a6cf0289d2df120f278864b8b94fdf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jul 2015 15:57:17 +0200 Subject: show warning when trying to highlight users that have left the conference --- .../eu/siacs/conversations/entities/MucOptions.java | 9 +++++++++ .../eu/siacs/conversations/ui/ConversationFragment.java | 17 ++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs') diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java index 6ff6b8c9a..52a862efa 100644 --- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java +++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java @@ -264,6 +264,15 @@ public class MucOptions { users.add(user); } + public boolean isUserInRoom(String name) { + for (int i = 0; i < users.size(); ++i) { + if (users.get(i).getName().equals(name)) { + return true; + } + } + return false; + } + public void processPacket(PresencePacket packet, PgpEngine pgp) { final Jid from = packet.getFrom(); if (!from.isBareJid()) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index f9144083a..6ff14d81b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -385,11 +385,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (message.getStatus() <= Message.STATUS_RECEIVED) { if (message.getConversation().getMode() == Conversation.MODE_MULTI) { if (message.getCounterpart() != null) { - if (!message.getCounterpart().isBareJid()) { - highlightInConference(message.getCounterpart().getResourcepart()); - } else { - highlightInConference(message.getCounterpart().toString()); + String user = message.getCounterpart().isBareJid() ? message.getCounterpart().toString() : message.getCounterpart().getResourcepart(); + if (!message.getConversation().getMucOptions().isUserInRoom(user)) { + Toast.makeText(activity,activity.getString(R.string.user_has_left_conference,user),Toast.LENGTH_SHORT).show(); } + highlightInConference(user); } } else { activity.switchToContactDetails(message.getContact()); @@ -410,7 +410,14 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (message.getStatus() <= Message.STATUS_RECEIVED) { if (message.getConversation().getMode() == Conversation.MODE_MULTI) { if (message.getCounterpart() != null) { - privateMessageWith(message.getCounterpart()); + String user = message.getCounterpart().getResourcepart(); + if (user != null) { + if (message.getConversation().getMucOptions().isUserInRoom(user)) { + privateMessageWith(message.getCounterpart()); + } else { + Toast.makeText(activity, activity.getString(R.string.user_has_left_conference, user), Toast.LENGTH_SHORT).show(); + } + } } } } else { -- cgit v1.2.3