From 3a627f72fbc5f51efaf3d8723fc7ce883f2f6e83 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 21 Apr 2015 18:36:11 +0200 Subject: fixed direct invites --- .../siacs/conversations/parser/MessageParser.java | 40 +++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 8ae9b642..76d01468 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -391,15 +391,17 @@ public class MessageParser extends AbstractParser implements private void parseNonMessage(Element packet, Account account) { final Jid from = packet.getAttributeAsJid("from"); + if (account.getJid().equals(from)) { + return; + } if (extractChatState(from == null ? null : mXmppConnectionService.find(account,from), packet)) { mXmppConnectionService.updateConversationUi(); } - Element invite = extractInvite(packet); - if (invite != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, from, true); + Invite invite = extractInvite(packet); + if (invite != null && invite.jid != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); if (!conversation.getMucOptions().online()) { - Element password = invite.findChild("password"); - conversation.getMucOptions().setPassword(password == null ? null : password.getContent()); + conversation.getMucOptions().setPassword(invite.password); mXmppConnectionService.databaseBackend.updateConversation(conversation); mXmppConnectionService.joinMuc(conversation); mXmppConnectionService.updateConversationUi(); @@ -439,16 +441,30 @@ public class MessageParser extends AbstractParser implements } } - private Element extractInvite(Element message) { - Element x = message.findChild("x","http://jabber.org/protocol/muc#user"); - if (x == null) { - x = message.findChild("x","jabber:x:conference"); + private class Invite { + Jid jid; + String password; + Invite(Jid jid, String password) { + this.jid = jid; + this.password = password; } - if (x != null && x.hasChild("invite")) { - return x; + } + + private Invite extractInvite(Element message) { + Element x = message.findChild("x","http://jabber.org/protocol/muc#user"); + if (x != null) { + Element invite = x.findChild("invite"); + if (invite != null) { + Element pw = x.findChild("password"); + return new Invite(message.getAttributeAsJid("from"), pw != null ? pw.getContent(): null); + } } else { - return null; + x = message.findChild("x","jabber:x:conference"); + if (x != null) { + return new Invite(x.getAttributeAsJid("jid"),x.getAttribute("password")); + } } + return null; } private void parseEvent(final Element event, final Jid from, final Account account) { -- cgit v1.2.3 From 5136bf9832b9a7aeb59926b42fe6a6632452c1ef Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 5 May 2015 06:17:34 +0200 Subject: r/o support for vcard avatars. pep avatars will be prefered --- .../java/eu/siacs/conversations/parser/MessageParser.java | 2 +- .../eu/siacs/conversations/parser/PresenceParser.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 76d01468..7870fdbf 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -494,7 +494,7 @@ public class MessageParser extends AbstractParser implements } else { Contact contact = account.getRoster().getContact( from); - contact.setAvatar(avatar.getFilename()); + contact.setAvatar(avatar); mXmppConnectionService.getAvatarService().clear( contact); mXmppConnectionService.updateConversationUi(); diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 7505b091..f7872210 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -13,6 +13,7 @@ import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.OnPresencePacketReceived; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.pep.Avatar; import eu.siacs.conversations.xmpp.stanzas.PresencePacket; public class PresenceParser extends AbstractParser implements @@ -101,6 +102,20 @@ public class PresenceParser extends AbstractParser implements if (nick != null) { contact.setPresenceName(nick.getContent()); } + Element x = packet.findChild("x","vcard-temp:x:update"); + Avatar avatar = Avatar.parsePresence(x); + if (avatar != null && !contact.isSelf()) { + avatar.owner = from.toBareJid(); + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { + if (contact.setAvatar(avatar)) { + mXmppConnectionService.getAvatarService().clear(contact); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.updateRosterUi(); + } + } else { + mXmppConnectionService.fetchAvatar(account,avatar); + } + } mXmppConnectionService.updateRosterUi(); } -- cgit v1.2.3 From e32f380dae4913d8152fc92b76193de241089cf8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 14 May 2015 14:42:21 +0200 Subject: provide helper function for getting the content of a child directly --- src/main/java/eu/siacs/conversations/parser/AbstractParser.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index bfe84440..6f73f24d 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -70,10 +70,6 @@ public abstract class AbstractParser { if (item == null) { return null; } - Element data = item.findChild("data", "urn:xmpp:avatar:data"); - if (data == null) { - return null; - } - return data.getContent(); + return item.findChildContent("data", "urn:xmpp:avatar:data"); } } -- cgit v1.2.3 From d261feda74ac3bd42d633d83264b14696276ade6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 05:14:15 +0200 Subject: rewrote parser code. mam id and possible other stuff still missing. also massivly untested --- .../siacs/conversations/parser/AbstractParser.java | 41 +- .../siacs/conversations/parser/MessageParser.java | 665 ++++++--------------- 2 files changed, 212 insertions(+), 494 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index 6f73f24d..7b3eb7e9 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -11,6 +11,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.stanzas.MessagePacket; public abstract class AbstractParser { @@ -20,22 +21,23 @@ public abstract class AbstractParser { this.mXmppConnectionService = service; } - protected long getTimestamp(Element packet) { - long now = System.currentTimeMillis(); - Element delay = packet.findChild("delay"); - if (delay == null) { - return now; - } - String stamp = delay.getAttribute("stamp"); - if (stamp == null) { - return now; - } - try { - long time = parseTimestamp(stamp).getTime(); - return now < time ? now : time; - } catch (ParseException e) { - return now; + public static Long getTimestamp(Element element, Long defaultValue) { + Element delay = element.findChild("delay"); + if (delay != null) { + String stamp = delay.getAttribute("stamp"); + if (stamp != null) { + try { + return AbstractParser.parseTimestamp(delay.getAttribute("stamp")).getTime(); + } catch (ParseException e) { + return defaultValue; + } + } } + return defaultValue; + } + + protected long getTimestamp(Element packet) { + return getTimestamp(packet,System.currentTimeMillis()); } public static Date parseTimestamp(String timestamp) throws ParseException { @@ -46,14 +48,11 @@ public abstract class AbstractParser { return dateFormat.parse(timestamp); } - protected void updateLastseen(final Element packet, final Account account, - final boolean presenceOverwrite) { - final Jid from = packet.getAttributeAsJid("from"); - updateLastseen(packet, account, from, presenceOverwrite); + protected void updateLastseen(final Element packet, final Account account, final boolean presenceOverwrite) { + updateLastseen(packet, account, packet.getAttributeAsJid("from"), presenceOverwrite); } - protected void updateLastseen(final Element packet, final Account account, final Jid from, - final boolean presenceOverwrite) { + protected void updateLastseen(final Element packet, final Account account, final Jid from, final boolean presenceOverwrite) { final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart(); final Contact contact = account.getRoster().getContact(from); final long timestamp = getTimestamp(packet); diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 7870fdbf..5a2fcbe1 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -1,8 +1,12 @@ package eu.siacs.conversations.parser; +import android.util.Log; +import android.util.Pair; + import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -25,12 +29,12 @@ public class MessageParser extends AbstractParser implements super(service); } - private boolean extractChatState(Conversation conversation, final Element element) { - ChatState state = ChatState.parse(element); + private boolean extractChatState(Conversation conversation, final MessagePacket packet) { + ChatState state = ChatState.parse(packet); if (state != null && conversation != null) { final Account account = conversation.getAccount(); - Jid from = element.getAttributeAsJid("from"); - if (from != null && from.toBareJid().equals(account.getJid().toBareJid())) { + Jid from = packet.getFrom(); + if (from.toBareJid().equals(account.getJid().toBareJid())) { conversation.setOutgoingChatState(state); return false; } else { @@ -40,86 +44,27 @@ public class MessageParser extends AbstractParser implements return false; } - private Message parseChat(MessagePacket packet, Account account) { - final Jid jid = packet.getFrom(); - if (jid == null) { - return null; - } - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid.toBareJid(), false); - String pgpBody = getPgpBody(packet); - Message finishedMessage; - if (pgpBody != null) { - finishedMessage = new Message(conversation, - pgpBody, Message.ENCRYPTION_PGP, Message.STATUS_RECEIVED); - } else { - finishedMessage = new Message(conversation, - packet.getBody(), Message.ENCRYPTION_NONE, - Message.STATUS_RECEIVED); - } - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - if (conversation.getMode() == Conversation.MODE_MULTI - && !jid.isBareJid()) { - final Jid trueCounterpart = conversation.getMucOptions() - .getTrueCounterpart(jid.getResourcepart()); - if (trueCounterpart != null) { - updateLastseen(packet, account, trueCounterpart, false); - } - finishedMessage.setType(Message.TYPE_PRIVATE); - finishedMessage.setTrueCounterpart(trueCounterpart); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - } else { - updateLastseen(packet, account, true); - } - finishedMessage.setCounterpart(jid); - finishedMessage.setTime(getTimestamp(packet)); - extractChatState(conversation,packet); - return finishedMessage; - } - - private Message parseOtrChat(MessagePacket packet, Account account) { - final Jid to = packet.getTo(); - final Jid from = packet.getFrom(); - if (to == null || from == null) { - return null; - } - boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, from.toBareJid(), false); + private Message parseOtrChat(String body, Jid from, String id, Conversation conversation) { String presence; if (from.isBareJid()) { presence = ""; } else { presence = from.getResourcepart(); } - extractChatState(conversation, packet); - updateLastseen(packet, account, true); - String body = packet.getBody(); if (body.matches("^\\?OTRv\\d{1,2}\\?.*")) { conversation.endOtrIfNeeded(); } if (!conversation.hasValidOtrSession()) { - if (properlyAddressed) { - conversation.startOtrSession(presence,false); - } else { - return null; - } + conversation.startOtrSession(presence,false); } else { - String foreignPresence = conversation.getOtrSession() - .getSessionID().getUserID(); + String foreignPresence = conversation.getOtrSession().getSessionID().getUserID(); if (!foreignPresence.equals(presence)) { conversation.endOtrIfNeeded(); - if (properlyAddressed) { - conversation.startOtrSession(presence, false); - } else { - return null; - } + conversation.startOtrSession(presence, false); } } try { - conversation.setLastReceivedOtrMessageId(packet.getId()); + conversation.setLastReceivedOtrMessageId(id); Session otrSession = conversation.getOtrSession(); SessionStatus before = otrSession.getSessionStatus(); body = otrSession.transformReceiving(body); @@ -140,12 +85,7 @@ public class MessageParser extends AbstractParser implements conversation.setSymmetricKey(CryptoHelper.hexToBytes(key)); return null; } - Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, - Message.STATUS_RECEIVED); - finishedMessage.setTime(getTimestamp(packet)); - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - finishedMessage.setCounterpart(from); + Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED); conversation.setLastReceivedOtrMessageId(null); return finishedMessage; } catch (Exception e) { @@ -154,293 +94,6 @@ public class MessageParser extends AbstractParser implements } } - private Message parseGroupchat(MessagePacket packet, Account account) { - int status; - final Jid from = packet.getFrom(); - if (from == null) { - return null; - } - if (mXmppConnectionService.find(account.pendingConferenceLeaves, - account, from.toBareJid()) != null) { - return null; - } - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, from.toBareJid(), true); - final Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(from.getResourcepart()); - if (trueCounterpart != null) { - updateLastseen(packet, account, trueCounterpart, false); - } - if (packet.hasChild("subject")) { - conversation.setHasMessagesLeftOnServer(true); - conversation.getMucOptions().setSubject(packet.findChild("subject").getContent()); - mXmppConnectionService.updateConversationUi(); - return null; - } - - final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); - if (from.isBareJid() && (x == null || !x.hasChild("status"))) { - return null; - } else if (from.isBareJid() && x.hasChild("status")) { - for(Element child : x.getChildren()) { - if (child.getName().equals("status")) { - String code = child.getAttribute("code"); - if (code.contains(MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED)) { - mXmppConnectionService.fetchConferenceConfiguration(conversation); - } - } - } - return null; - } - - if (from.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { - if (mXmppConnectionService.markMessage(conversation, - packet.getId(), Message.STATUS_SEND_RECEIVED)) { - return null; - } else if (packet.getId() == null) { - Message message = conversation.findSentMessageWithBody(packet.getBody()); - if (message != null) { - mXmppConnectionService.markMessage(message,Message.STATUS_SEND_RECEIVED); - return null; - } else { - status = Message.STATUS_SEND; - } - } else { - status = Message.STATUS_SEND; - } - } else { - status = Message.STATUS_RECEIVED; - } - String pgpBody = getPgpBody(packet); - Message finishedMessage; - if (pgpBody == null) { - finishedMessage = new Message(conversation, - packet.getBody(), Message.ENCRYPTION_NONE, status); - } else { - finishedMessage = new Message(conversation, pgpBody, - Message.ENCRYPTION_PGP, status); - } - finishedMessage.setRemoteMsgId(packet.getId()); - finishedMessage.markable = isMarkable(packet); - finishedMessage.setCounterpart(from); - if (status == Message.STATUS_RECEIVED) { - finishedMessage.setTrueCounterpart(conversation.getMucOptions() - .getTrueCounterpart(from.getResourcepart())); - } - if (packet.hasChild("delay") - && conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - finishedMessage.setTime(getTimestamp(packet)); - return finishedMessage; - } - - private Message parseCarbonMessage(final MessagePacket packet, final Account account) { - int status; - final Jid fullJid; - Element forwarded; - if (packet.hasChild("received", "urn:xmpp:carbons:2")) { - forwarded = packet.findChild("received", "urn:xmpp:carbons:2") - .findChild("forwarded", "urn:xmpp:forward:0"); - status = Message.STATUS_RECEIVED; - } else if (packet.hasChild("sent", "urn:xmpp:carbons:2")) { - forwarded = packet.findChild("sent", "urn:xmpp:carbons:2") - .findChild("forwarded", "urn:xmpp:forward:0"); - status = Message.STATUS_SEND; - } else { - return null; - } - if (forwarded == null) { - return null; - } - Element message = forwarded.findChild("message"); - if (message == null) { - return null; - } - if (!message.hasChild("body")) { - if (status == Message.STATUS_RECEIVED - && message.getAttribute("from") != null) { - parseNonMessage(message, account); - } else if (status == Message.STATUS_SEND - && message.hasChild("displayed", "urn:xmpp:chat-markers:0")) { - final Jid to = message.getAttributeAsJid("to"); - if (to != null) { - final Conversation conversation = mXmppConnectionService.find( - mXmppConnectionService.getConversations(), account, - to.toBareJid()); - if (conversation != null) { - mXmppConnectionService.markRead(conversation); - } - } - } - return null; - } - if (status == Message.STATUS_RECEIVED) { - fullJid = message.getAttributeAsJid("from"); - if (fullJid == null) { - return null; - } else { - updateLastseen(message, account, true); - } - } else { - fullJid = message.getAttributeAsJid("to"); - if (fullJid == null) { - return null; - } - } - if (message.hasChild("x","http://jabber.org/protocol/muc#user") - && "chat".equals(message.getAttribute("type"))) { - return null; - } - Conversation conversation = mXmppConnectionService - .findOrCreateConversation(account, fullJid.toBareJid(), false); - String pgpBody = getPgpBody(message); - Message finishedMessage; - if (pgpBody != null) { - finishedMessage = new Message(conversation, pgpBody, - Message.ENCRYPTION_PGP, status); - } else { - String body = message.findChild("body").getContent(); - finishedMessage = new Message(conversation, body, - Message.ENCRYPTION_NONE, status); - } - extractChatState(conversation,message); - finishedMessage.setTime(getTimestamp(message)); - finishedMessage.setRemoteMsgId(message.getAttribute("id")); - finishedMessage.markable = isMarkable(message); - finishedMessage.setCounterpart(fullJid); - if (conversation.getMode() == Conversation.MODE_MULTI - && !fullJid.isBareJid()) { - finishedMessage.setType(Message.TYPE_PRIVATE); - finishedMessage.setTrueCounterpart(conversation.getMucOptions() - .getTrueCounterpart(fullJid.getResourcepart())); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - } - return finishedMessage; - } - - private Message parseMamMessage(MessagePacket packet, final Account account) { - final Element result = packet.findChild("result","urn:xmpp:mam:0"); - if (result == null ) { - return null; - } - final MessageArchiveService.Query query = this.mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); - if (query!=null) { - query.incrementTotalCount(); - } - final Element forwarded = result.findChild("forwarded","urn:xmpp:forward:0"); - if (forwarded == null) { - return null; - } - final Element message = forwarded.findChild("message"); - if (message == null) { - return null; - } - final Element body = message.findChild("body"); - if (body == null || message.hasChild("private","urn:xmpp:carbons:2") || message.hasChild("no-copy","urn:xmpp:hints")) { - return null; - } - int encryption; - String content = getPgpBody(message); - if (content != null) { - encryption = Message.ENCRYPTION_PGP; - } else { - encryption = Message.ENCRYPTION_NONE; - content = body.getContent(); - } - if (content == null) { - return null; - } - final long timestamp = getTimestamp(forwarded); - final Jid to = message.getAttributeAsJid("to"); - final Jid from = message.getAttributeAsJid("from"); - Jid counterpart; - int status; - Conversation conversation; - if (from!=null && to != null && from.toBareJid().equals(account.getJid().toBareJid())) { - status = Message.STATUS_SEND; - conversation = this.mXmppConnectionService.findOrCreateConversation(account,to.toBareJid(),false,query); - counterpart = to; - } else if (from !=null && to != null) { - status = Message.STATUS_RECEIVED; - conversation = this.mXmppConnectionService.findOrCreateConversation(account,from.toBareJid(),false,query); - counterpart = from; - } else { - return null; - } - Message finishedMessage = new Message(conversation,content,encryption,status); - finishedMessage.setTime(timestamp); - finishedMessage.setCounterpart(counterpart); - finishedMessage.setRemoteMsgId(message.getAttribute("id")); - finishedMessage.setServerMsgId(result.getAttribute("id")); - if (conversation.hasDuplicateMessage(finishedMessage)) { - return null; - } - if (query!=null) { - query.incrementMessageCount(); - } - return finishedMessage; - } - - private void parseError(final MessagePacket packet, final Account account) { - final Jid from = packet.getFrom(); - mXmppConnectionService.markMessage(account, from.toBareJid(), - packet.getId(), Message.STATUS_SEND_FAILED); - } - - private void parseNonMessage(Element packet, Account account) { - final Jid from = packet.getAttributeAsJid("from"); - if (account.getJid().equals(from)) { - return; - } - if (extractChatState(from == null ? null : mXmppConnectionService.find(account,from), packet)) { - mXmppConnectionService.updateConversationUi(); - } - Invite invite = extractInvite(packet); - if (invite != null && invite.jid != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); - if (!conversation.getMucOptions().online()) { - conversation.getMucOptions().setPassword(invite.password); - mXmppConnectionService.databaseBackend.updateConversation(conversation); - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } - } - if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { - Element event = packet.findChild("event", - "http://jabber.org/protocol/pubsub#event"); - parseEvent(event, from, account); - } else if (from != null && packet.hasChild("displayed", "urn:xmpp:chat-markers:0")) { - String id = packet - .findChild("displayed", "urn:xmpp:chat-markers:0") - .getAttribute("id"); - updateLastseen(packet, account, true); - final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), id, Message.STATUS_SEND_DISPLAYED); - Message message = displayedMessage == null ? null :displayedMessage.prev(); - while (message != null - && message.getStatus() == Message.STATUS_SEND_RECEIVED - && message.getTimeSent() < displayedMessage.getTimeSent()) { - mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED); - message = message.prev(); - } - } else if (from != null - && packet.hasChild("received", "urn:xmpp:chat-markers:0")) { - String id = packet.findChild("received", "urn:xmpp:chat-markers:0") - .getAttribute("id"); - updateLastseen(packet, account, false); - mXmppConnectionService.markMessage(account, from.toBareJid(), - id, Message.STATUS_SEND_RECEIVED); - } else if (from != null - && packet.hasChild("received", "urn:xmpp:receipts")) { - String id = packet.findChild("received", "urn:xmpp:receipts") - .getAttribute("id"); - updateLastseen(packet, account, false); - mXmppConnectionService.markMessage(account, from.toBareJid(), - id, Message.STATUS_SEND_RECEIVED); - } - } - private class Invite { Jid jid; String password; @@ -451,7 +104,7 @@ public class MessageParser extends AbstractParser implements } private Invite extractInvite(Element message) { - Element x = message.findChild("x","http://jabber.org/protocol/muc#user"); + Element x = message.findChild("x", "http://jabber.org/protocol/muc#user"); if (x != null) { Element invite = x.findChild("invite"); if (invite != null) { @@ -523,142 +176,208 @@ public class MessageParser extends AbstractParser implements } } - private String getPgpBody(Element message) { - Element child = message.findChild("x", "jabber:x:encrypted"); - if (child == null) { - return null; + @Override + public void onMessagePacketReceived(Account account, MessagePacket original) { + final MessagePacket packet; + Long timestamp = null; + final boolean isForwarded; + boolean carbon = false; //live carbons or mam-sub + if (original.fromServer(account)) { + Pair f; + f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); + f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f; + f = f == null ? original.getForwardedMessagePacket("result", "urn:xmpp:mam:0") : f; + packet = f != null ? f.first : original; + timestamp = f != null ? f.second : null; + isForwarded = f != null; + carbon = original.hasChild("received", "urn:xmpp:carbons:2") || original.hasChild("received", "urn:xmpp:carbons:2"); + + Element fin = packet.findChild("fin", "urn:xmpp:mam:0"); + if (fin != null) { + mXmppConnectionService.getMessageArchiveService().processFin(fin); + return; + } + } else { - return child.getContent(); + packet = original; + isForwarded = false; + } + if (timestamp == null) { + timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis()); + } + final String body = packet.getBody(); + final String encrypted = packet.findChildContent("x", "jabber:x:encrypted"); + int status; + final Jid to = packet.getTo(); + final Jid from = packet.getFrom(); + final Jid counterpart; + final String id = packet.getId(); + boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; + boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; + if (packet.fromAccount(account)) { + status = Message.STATUS_SEND; + counterpart = to; + } else { + status = Message.STATUS_RECEIVED; + counterpart = from; } - } - private boolean isMarkable(Element message) { - return message.hasChild("markable", "urn:xmpp:chat-markers:0"); - } + if (from == null || to == null) { + Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); + return; + } - @Override - public void onMessagePacketReceived(Account account, MessagePacket packet) { - Message message = null; - this.parseNick(packet, account); - if ((packet.getType() == MessagePacket.TYPE_CHAT || packet.getType() == MessagePacket.TYPE_NORMAL)) { - if ((packet.getBody() != null) - && (packet.getBody().startsWith("?OTR"))) { - message = this.parseOtrChat(packet, account); - if (message != null) { - message.markUnread(); - } - } else if (packet.hasChild("body") && extractInvite(packet) == null) { - message = this.parseChat(packet, account); - if (message != null) { - message.markUnread(); - } - } else if (packet.hasChild("received", "urn:xmpp:carbons:2") - || (packet.hasChild("sent", "urn:xmpp:carbons:2"))) { - message = this.parseCarbonMessage(packet, account); - if (message != null) { - if (message.getStatus() == Message.STATUS_SEND) { - account.activateGracePeriod(); - mXmppConnectionService.markRead(message.getConversation()); - } else { - message.markUnread(); + Invite invite = extractInvite(packet); + if (invite != null && invite.jid != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); + if (!conversation.getMucOptions().online()) { + conversation.getMucOptions().setPassword(invite.password); + mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.joinMuc(conversation); + mXmppConnectionService.updateConversationUi(); + } + return; + } + + if (extractChatState(mXmppConnectionService.find(account,from), packet)) { + mXmppConnectionService.updateConversationUi(); + } + + if (body != null || encrypted != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); + if (isTypeGroupChat) { + if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { + status = Message.STATUS_SEND; + if (mXmppConnectionService.markMessage(conversation, id, Message.STATUS_SEND_RECEIVED)) { + return; + } else if (id == null) { + Message message = conversation.findSentMessageWithBody(packet.getBody()); + if (message != null) { + mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); + return; + } } + } else { + status = Message.STATUS_RECEIVED; } - } else if (packet.hasChild("result","urn:xmpp:mam:0")) { - message = parseMamMessage(packet, account); - if (message != null) { - Conversation conversation = message.getConversation(); - conversation.add(message); - mXmppConnectionService.databaseBackend.createMessage(message); + } + Message message; + if (body != null && body.startsWith("?OTR")) { + if (!isForwarded && !isTypeGroupChat && properlyAddressed) { + message = parseOtrChat(body, from, id, conversation); + if (message == null) { + return; + } + } else { + message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } - return; - } else if (packet.hasChild("fin","urn:xmpp:mam:0")) { - Element fin = packet.findChild("fin","urn:xmpp:mam:0"); - mXmppConnectionService.getMessageArchiveService().processFin(fin); + } else if (encrypted != null) { + message = new Message(conversation, encrypted, Message.ENCRYPTION_PGP, status); } else { - parseNonMessage(packet, account); + message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } - } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) { - message = this.parseGroupchat(packet, account); - if (message != null) { - if (message.getStatus() == Message.STATUS_RECEIVED) { - message.markUnread(); - } else { - mXmppConnectionService.markRead(message.getConversation()); - account.activateGracePeriod(); + message.setCounterpart(counterpart); + message.setRemoteMsgId(id); + message.setTime(timestamp); + message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); + if (conversation.getMode() == Conversation.MODE_MULTI) { + message.setTrueCounterpart(conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart())); + if (!isTypeGroupChat) { + message.setType(Message.TYPE_PRIVATE); } } - } else if (packet.getType() == MessagePacket.TYPE_ERROR) { - this.parseError(packet, account); - return; - } else if (packet.getType() == MessagePacket.TYPE_HEADLINE) { - this.parseHeadline(packet, account); - return; - } - if ((message == null) || (message.getBody() == null)) { - return; - } - if ((mXmppConnectionService.confirmMessages()) - && ((packet.getId() != null))) { - if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, - "urn:xmpp:chat-markers:0"); - mXmppConnectionService.sendMessagePacket(account, receipt); + updateLastseen(packet,account,true); + conversation.add(message); + if (carbon || status == Message.STATUS_RECEIVED) { + mXmppConnectionService.markRead(conversation); + account.activateGracePeriod(); + } else if (!isForwarded) { + message.markUnread(); } - if (packet.hasChild("request", "urn:xmpp:receipts")) { - MessagePacket receipt = mXmppConnectionService - .getMessageGenerator().received(account, packet, - "urn:xmpp:receipts"); - mXmppConnectionService.sendMessagePacket(account, receipt); + + + if (mXmppConnectionService.confirmMessages() && id != null && !packet.fromAccount(account)) { + if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { + MessagePacket receipt = mXmppConnectionService + .getMessageGenerator().received(account, packet, "urn:xmpp:chat-markers:0"); + mXmppConnectionService.sendMessagePacket(account, receipt); + } + if (packet.hasChild("request", "urn:xmpp:receipts")) { + MessagePacket receipt = mXmppConnectionService + .getMessageGenerator().received(account, packet, "urn:xmpp:receipts"); + mXmppConnectionService.sendMessagePacket(account, receipt); + } } - } - Conversation conversation = message.getConversation(); - conversation.add(message); - if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().advancedStreamFeaturesLoaded()) { - if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { - mXmppConnectionService.updateConversation(conversation); + if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().advancedStreamFeaturesLoaded()) { + if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { + mXmppConnectionService.updateConversation(conversation); + } } - } - if (message.getStatus() == Message.STATUS_RECEIVED - && conversation.getOtrSession() != null - && !conversation.getOtrSession().getSessionID().getUserID() - .equals(message.getCounterpart().getResourcepart())) { - conversation.endOtrIfNeeded(); - } + if (message.getStatus() == Message.STATUS_RECEIVED + && conversation.getOtrSession() != null + && !conversation.getOtrSession().getSessionID().getUserID() + .equals(message.getCounterpart().getResourcepart())) { + conversation.endOtrIfNeeded(); + } - if (packet.getType() != MessagePacket.TYPE_ERROR) { if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) { mXmppConnectionService.databaseBackend.createMessage(message); } + final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); + if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { + manager.createNewConnection(message); + } else if (!message.isRead()) { + mXmppConnectionService.getNotificationService().push(message); + } + mXmppConnectionService.updateConversationUi(); + } else { + if (packet.hasChild("subject") && isTypeGroupChat) { + Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); + if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setHasMessagesLeftOnServer(true); + conversation.getMucOptions().setSubject(packet.findChildContent("subject")); + mXmppConnectionService.updateConversationUi(); + return; + } + } } - final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); - if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { - manager.createNewConnection(message); - } else if (!message.isRead()) { - mXmppConnectionService.getNotificationService().push(message); + + Element received = packet.findChild("received", "urn:xmpp:chat-markers:0"); + if (received == null) { + received = packet.findChild("received", "urn:xmpp:receipts"); + } + if (received != null && !packet.fromAccount(account)) { + mXmppConnectionService.markMessage(account, from.toBareJid(), received.getAttribute("id"), Message.STATUS_SEND_RECEIVED); + } + Element displayed = packet.findChild("displayed", "urn:xmpp:chat-markers:0"); + if (displayed != null) { + if (packet.fromAccount(account)) { + Conversation conversation = mXmppConnectionService.find(account,counterpart.toBareJid()); + mXmppConnectionService.markRead(conversation); + } else { + updateLastseen(packet, account, true); + final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED); + Message message = displayedMessage == null ? null : displayedMessage.prev(); + while (message != null + && message.getStatus() == Message.STATUS_SEND_RECEIVED + && message.getTimeSent() < displayedMessage.getTimeSent()) { + mXmppConnectionService.markMessage(message, Message.STATUS_SEND_DISPLAYED); + message = message.prev(); + } + } } - mXmppConnectionService.updateConversationUi(); - } - private void parseHeadline(MessagePacket packet, Account account) { - if (packet.hasChild("event", "http://jabber.org/protocol/pubsub#event")) { - Element event = packet.findChild("event", - "http://jabber.org/protocol/pubsub#event"); - parseEvent(event, packet.getFrom(), account); + Element event = packet.findChild("event", "http://jabber.org/protocol/pubsub#event"); + if (event != null) { + parseEvent(event, from, account); } - } - private void parseNick(MessagePacket packet, Account account) { - Element nick = packet.findChild("nick", - "http://jabber.org/protocol/nick"); + String nick = packet.findChildContent("nick", "http://jabber.org/protocol/nick"); if (nick != null) { - if (packet.getFrom() != null) { - Contact contact = account.getRoster().getContact( - packet.getFrom()); - contact.setPresenceName(nick.getContent()); - } + Contact contact = account.getRoster().getContact(from); + contact.setPresenceName(nick); } } -} +} \ No newline at end of file -- cgit v1.2.3 From b731995a517932d1c86877da13dd69d66cbb23c1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 06:31:27 +0200 Subject: added mam stuff to new message parser --- .../siacs/conversations/parser/AbstractParser.java | 2 +- .../siacs/conversations/parser/MessageParser.java | 33 +++++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index 7b3eb7e9..24e93db1 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -22,7 +22,7 @@ public abstract class AbstractParser { } public static Long getTimestamp(Element element, Long defaultValue) { - Element delay = element.findChild("delay"); + Element delay = element.findChild("delay","urn:xmpp:delay"); if (delay != null) { String stamp = delay.getAttribute("stamp"); if (stamp != null) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 5a2fcbe1..69f58898 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -182,6 +182,8 @@ public class MessageParser extends AbstractParser implements Long timestamp = null; final boolean isForwarded; boolean carbon = false; //live carbons or mam-sub + MessageArchiveService.Query query = null; + String serverMsgId = null; if (original.fromServer(account)) { Pair f; f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); @@ -198,6 +200,14 @@ public class MessageParser extends AbstractParser implements return; } + final Element result = packet.findChild("result","urn:xmpp:mam:0"); + if (result != null) { + query = mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); + if (query != null) { + query.incrementTotalCount(); + } + serverMsgId = result.getAttribute("id"); + } } else { packet = original; isForwarded = false; @@ -211,7 +221,7 @@ public class MessageParser extends AbstractParser implements final Jid to = packet.getTo(); final Jid from = packet.getFrom(); final Jid counterpart; - final String id = packet.getId(); + final String remoteMsgId = packet.getId(); boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; if (packet.fromAccount(account)) { @@ -229,7 +239,7 @@ public class MessageParser extends AbstractParser implements Invite invite = extractInvite(packet); if (invite != null && invite.jid != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true); + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true,query); if (!conversation.getMucOptions().online()) { conversation.getMucOptions().setPassword(invite.password); mXmppConnectionService.databaseBackend.updateConversation(conversation); @@ -248,9 +258,9 @@ public class MessageParser extends AbstractParser implements if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { status = Message.STATUS_SEND; - if (mXmppConnectionService.markMessage(conversation, id, Message.STATUS_SEND_RECEIVED)) { + if (mXmppConnectionService.markMessage(conversation, remoteMsgId, Message.STATUS_SEND_RECEIVED)) { return; - } else if (id == null) { + } else if (remoteMsgId == null) { Message message = conversation.findSentMessageWithBody(packet.getBody()); if (message != null) { mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); @@ -264,7 +274,7 @@ public class MessageParser extends AbstractParser implements Message message; if (body != null && body.startsWith("?OTR")) { if (!isForwarded && !isTypeGroupChat && properlyAddressed) { - message = parseOtrChat(body, from, id, conversation); + message = parseOtrChat(body, from, remoteMsgId, conversation); if (message == null) { return; } @@ -277,7 +287,8 @@ public class MessageParser extends AbstractParser implements message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } message.setCounterpart(counterpart); - message.setRemoteMsgId(id); + message.setRemoteMsgId(remoteMsgId); + message.setServerMsgId(serverMsgId); message.setTime(timestamp); message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); if (conversation.getMode() == Conversation.MODE_MULTI) { @@ -287,6 +298,14 @@ public class MessageParser extends AbstractParser implements } } updateLastseen(packet,account,true); + boolean checkForDuplicates = serverMsgId != null || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")); + if (checkForDuplicates && conversation.hasDuplicateMessage(message)) { + Log.d(Config.LOGTAG,"skipping duplicate message from "+message.getCounterpart().toString()+" "+message.getBody()); + return; + } + if (query != null) { + query.incrementMessageCount(); + } conversation.add(message); if (carbon || status == Message.STATUS_RECEIVED) { mXmppConnectionService.markRead(conversation); @@ -296,7 +315,7 @@ public class MessageParser extends AbstractParser implements } - if (mXmppConnectionService.confirmMessages() && id != null && !packet.fromAccount(account)) { + if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded) { if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { MessagePacket receipt = mXmppConnectionService .getMessageGenerator().received(account, packet, "urn:xmpp:chat-markers:0"); -- cgit v1.2.3 From eeebebe32afef42cb3be07641d0c008a67f766ab Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 11:51:20 +0200 Subject: fixed read/unread markers --- .../eu/siacs/conversations/parser/MessageParser.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 69f58898..339aeb7f 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -181,7 +181,6 @@ public class MessageParser extends AbstractParser implements final MessagePacket packet; Long timestamp = null; final boolean isForwarded; - boolean carbon = false; //live carbons or mam-sub MessageArchiveService.Query query = null; String serverMsgId = null; if (original.fromServer(account)) { @@ -192,15 +191,14 @@ public class MessageParser extends AbstractParser implements packet = f != null ? f.first : original; timestamp = f != null ? f.second : null; isForwarded = f != null; - carbon = original.hasChild("received", "urn:xmpp:carbons:2") || original.hasChild("received", "urn:xmpp:carbons:2"); - Element fin = packet.findChild("fin", "urn:xmpp:mam:0"); + Element fin = original.findChild("fin", "urn:xmpp:mam:0"); if (fin != null) { mXmppConnectionService.getMessageArchiveService().processFin(fin); return; } - final Element result = packet.findChild("result","urn:xmpp:mam:0"); + final Element result = original.findChild("result","urn:xmpp:mam:0"); if (result != null) { query = mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); if (query != null) { @@ -307,14 +305,15 @@ public class MessageParser extends AbstractParser implements query.incrementMessageCount(); } conversation.add(message); - if (carbon || status == Message.STATUS_RECEIVED) { - mXmppConnectionService.markRead(conversation); - account.activateGracePeriod(); - } else if (!isForwarded) { - message.markUnread(); + if (serverMsgId == null) { + if (status == Message.STATUS_SEND) { + mXmppConnectionService.markRead(conversation); + account.activateGracePeriod(); + } else { + message.markUnread(); + } } - if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded) { if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { MessagePacket receipt = mXmppConnectionService -- cgit v1.2.3 From 1b5631c835d34fc9f7a3474b015a21ffc64ed0d2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 May 2015 12:29:45 +0200 Subject: fixed muc mam. added a few security checks --- .../siacs/conversations/parser/MessageParser.java | 48 +++++++++++----------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 339aeb7f..d254a863 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -181,31 +181,34 @@ public class MessageParser extends AbstractParser implements final MessagePacket packet; Long timestamp = null; final boolean isForwarded; - MessageArchiveService.Query query = null; String serverMsgId = null; - if (original.fromServer(account)) { + final Element fin = original.findChild("fin", "urn:xmpp:mam:0"); + if (fin != null) { + mXmppConnectionService.getMessageArchiveService().processFin(fin,original.getFrom()); + return; + } + final Element result = original.findChild("result","urn:xmpp:mam:0"); + final MessageArchiveService.Query query = result == null ? null : mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); + if (query != null && query.validFrom(original.getFrom())) { + Pair f = original.getForwardedMessagePacket("result", "urn:xmpp:mam:0"); + if (f == null) { + return; + } + timestamp = f.second; + packet = f.first; + isForwarded = true; + serverMsgId = result.getAttribute("id"); + query.incrementTotalCount(); + } else if (query != null) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": received mam result from invalid sender"); + return; + } else if (original.fromServer(account)) { Pair f; f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f; - f = f == null ? original.getForwardedMessagePacket("result", "urn:xmpp:mam:0") : f; packet = f != null ? f.first : original; timestamp = f != null ? f.second : null; isForwarded = f != null; - - Element fin = original.findChild("fin", "urn:xmpp:mam:0"); - if (fin != null) { - mXmppConnectionService.getMessageArchiveService().processFin(fin); - return; - } - - final Element result = original.findChild("result","urn:xmpp:mam:0"); - if (result != null) { - query = mXmppConnectionService.getMessageArchiveService().findQuery(result.getAttribute("queryid")); - if (query != null) { - query.incrementTotalCount(); - } - serverMsgId = result.getAttribute("id"); - } } else { packet = original; isForwarded = false; @@ -216,9 +219,9 @@ public class MessageParser extends AbstractParser implements final String body = packet.getBody(); final String encrypted = packet.findChildContent("x", "jabber:x:encrypted"); int status; + final Jid counterpart; final Jid to = packet.getTo(); final Jid from = packet.getFrom(); - final Jid counterpart; final String remoteMsgId = packet.getId(); boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; @@ -312,6 +315,7 @@ public class MessageParser extends AbstractParser implements } else { message.markUnread(); } + mXmppConnectionService.updateConversationUi(); } if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded) { @@ -339,8 +343,7 @@ public class MessageParser extends AbstractParser implements conversation.endOtrIfNeeded(); } - if (message.getEncryption() == Message.ENCRYPTION_NONE - || mXmppConnectionService.saveEncryptedMessages()) { + if (message.getEncryption() == Message.ENCRYPTION_NONE || mXmppConnectionService.saveEncryptedMessages()) { mXmppConnectionService.databaseBackend.createMessage(message); } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); @@ -349,8 +352,7 @@ public class MessageParser extends AbstractParser implements } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); } - mXmppConnectionService.updateConversationUi(); - } else { + } else { //no body if (packet.hasChild("subject") && isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { -- cgit v1.2.3 From 9658146575841c402f1492bcc53b02bdddc4d458 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 May 2015 12:43:38 +0200 Subject: fixed npe in new message parser --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d254a863..d2fa2c24 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -375,7 +375,9 @@ public class MessageParser extends AbstractParser implements if (displayed != null) { if (packet.fromAccount(account)) { Conversation conversation = mXmppConnectionService.find(account,counterpart.toBareJid()); - mXmppConnectionService.markRead(conversation); + if (conversation != null) { + mXmppConnectionService.markRead(conversation); + } } else { updateLastseen(packet, account, true); final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED); -- cgit v1.2.3 From 201bc158bd9fa77c1ffcea53758280bd830e5710 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 19 May 2015 08:23:12 +0200 Subject: proper error parsing. some clean up --- .../siacs/conversations/parser/MessageParser.java | 90 ++++++++++++---------- 1 file changed, 49 insertions(+), 41 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d2fa2c24..1e683892 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -101,6 +101,20 @@ public class MessageParser extends AbstractParser implements this.jid = jid; this.password = password; } + + public boolean execute(Account account) { + if (jid != null) { + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, jid, true); + if (!conversation.getMucOptions().online()) { + conversation.getMucOptions().setPassword(password); + mXmppConnectionService.databaseBackend.updateConversation(conversation); + mXmppConnectionService.joinMuc(conversation); + mXmppConnectionService.updateConversationUi(); + } + return true; + } + return false; + } } private Invite extractInvite(Element message) { @@ -122,34 +136,23 @@ public class MessageParser extends AbstractParser implements private void parseEvent(final Element event, final Jid from, final Account account) { Element items = event.findChild("items"); - if (items == null) { - return; - } - String node = items.getAttribute("node"); - if (node == null) { - return; - } - if (node.equals("urn:xmpp:avatar:metadata")) { + String node = items == null ? null : items.getAttribute("node"); + if ("urn:xmpp:avatar:metadata".equals(node)) { Avatar avatar = Avatar.parseMetadata(items); if (avatar != null) { avatar.owner = from; - if (mXmppConnectionService.getFileBackend().isAvatarCached( - avatar)) { + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { if (account.getJid().toBareJid().equals(from)) { if (account.setAvatar(avatar.getFilename())) { - mXmppConnectionService.databaseBackend - .updateAccount(account); + mXmppConnectionService.databaseBackend.updateAccount(account); } - mXmppConnectionService.getAvatarService().clear( - account); + mXmppConnectionService.getAvatarService().clear(account); mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateAccountUi(); } else { - Contact contact = account.getRoster().getContact( - from); + Contact contact = account.getRoster().getContact(from); contact.setAvatar(avatar); - mXmppConnectionService.getAvatarService().clear( - contact); + mXmppConnectionService.getAvatarService().clear(contact); mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateRosterUi(); } @@ -157,27 +160,35 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.fetchAvatar(account, avatar); } } - } else if (node.equals("http://jabber.org/protocol/nick")) { - Element item = items.findChild("item"); - if (item != null) { - Element nick = item.findChild("nick", - "http://jabber.org/protocol/nick"); - if (nick != null) { - if (from != null) { - Contact contact = account.getRoster().getContact( - from); - contact.setPresenceName(nick.getContent()); - mXmppConnectionService.getAvatarService().clear(account); - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.updateAccountUi(); - } - } + } else if ("http://jabber.org/protocol/nick".equals(node)) { + Element i = items.findChild("item"); + Element nick = i == null ? null : i.findChild("nick", "http://jabber.org/protocol/nick"); + if (nick != null) { + Contact contact = account.getRoster().getContact(from); + contact.setPresenceName(nick.getContent()); + mXmppConnectionService.getAvatarService().clear(account); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.updateAccountUi(); } } } + private boolean handleErrorMessage(Account account, MessagePacket packet) { + if (packet.getType() == MessagePacket.TYPE_ERROR) { + Jid from = packet.getFrom(); + if (from != null) { + mXmppConnectionService.markMessage(account, from.toBareJid(), packet.getId(), Message.STATUS_SEND_FAILED); + } + return true; + } + return false; + } + @Override public void onMessagePacketReceived(Account account, MessagePacket original) { + if (handleErrorMessage(account, original)) { + return; + } final MessagePacket packet; Long timestamp = null; final boolean isForwarded; @@ -207,12 +218,16 @@ public class MessageParser extends AbstractParser implements f = original.getForwardedMessagePacket("received", "urn:xmpp:carbons:2"); f = f == null ? original.getForwardedMessagePacket("sent", "urn:xmpp:carbons:2") : f; packet = f != null ? f.first : original; + if (handleErrorMessage(account, packet)) { + return; + } timestamp = f != null ? f.second : null; isForwarded = f != null; } else { packet = original; isForwarded = false; } + if (timestamp == null) { timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis()); } @@ -239,14 +254,7 @@ public class MessageParser extends AbstractParser implements } Invite invite = extractInvite(packet); - if (invite != null && invite.jid != null) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, invite.jid, true,query); - if (!conversation.getMucOptions().online()) { - conversation.getMucOptions().setPassword(invite.password); - mXmppConnectionService.databaseBackend.updateConversation(conversation); - mXmppConnectionService.joinMuc(conversation); - mXmppConnectionService.updateConversationUi(); - } + if (invite != null && invite.execute(account)) { return; } -- cgit v1.2.3 From 402e5363d1db774e5e244948a2f0e961b48bb0a7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 26 May 2015 12:00:55 +0200 Subject: deduplicate private muc messages --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 1e683892..898613e3 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -307,7 +307,9 @@ public class MessageParser extends AbstractParser implements } } updateLastseen(packet,account,true); - boolean checkForDuplicates = serverMsgId != null || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")); + boolean checkForDuplicates = serverMsgId != null + || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")) + || message.getType() == Message.TYPE_PRIVATE; if (checkForDuplicates && conversation.hasDuplicateMessage(message)) { Log.d(Config.LOGTAG,"skipping duplicate message from "+message.getCounterpart().toString()+" "+message.getBody()); return; -- cgit v1.2.3 From 165965bb83bb3ee9750b8cfecea87ddb154fc649 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 27 May 2015 11:44:44 +0200 Subject: parse nick and avatar only from available presences to avoid potential error reflection --- .../siacs/conversations/parser/PresenceParser.java | 73 ++++++++-------------- 1 file changed, 26 insertions(+), 47 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index f7872210..d83347d8 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -45,38 +45,37 @@ public class PresenceParser extends AbstractParser implements } public void parseContactPresence(PresencePacket packet, Account account) { - PresenceGenerator mPresenceGenerator = mXmppConnectionService - .getPresenceGenerator(); - if (packet.getFrom() == null) { + PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator(); + final Jid from = packet.getFrom(); + if (from == null) { return; } - final Jid from = packet.getFrom(); - String type = packet.getAttribute("type"); - Contact contact = account.getRoster().getContact(packet.getFrom()); + final String type = packet.getAttribute("type"); + final Contact contact = account.getRoster().getContact(from); if (type == null) { - String presence; - if (!from.isBareJid()) { - presence = from.getResourcepart(); - } else { - presence = ""; + String presence = from.isBareJid() ? "" : from.getResourcepart(); + contact.setPresenceName(packet.findChildContent("nick", "http://jabber.org/protocol/nick")); + Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update")); + if (avatar != null && !contact.isSelf()) { + avatar.owner = from.toBareJid(); + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { + if (contact.setAvatar(avatar)) { + mXmppConnectionService.getAvatarService().clear(contact); + mXmppConnectionService.updateConversationUi(); + mXmppConnectionService.updateRosterUi(); + } + } else { + mXmppConnectionService.fetchAvatar(account, avatar); + } } int sizeBefore = contact.getPresences().size(); - contact.updatePresence(presence, - Presences.parseShow(packet.findChild("show"))); + contact.updatePresence(presence, Presences.parseShow(packet.findChild("show"))); PgpEngine pgp = mXmppConnectionService.getPgpEngine(); - if (pgp != null) { - Element x = packet.findChild("x", "jabber:x:signed"); - if (x != null) { - Element status = packet.findChild("status"); - String msg; - if (status != null) { - msg = status.getContent(); - } else { - msg = ""; - } - contact.setPgpKeyId(pgp.fetchKeyId(account, msg, - x.getContent())); - } + Element x = packet.findChild("x", "jabber:x:signed"); + if (pgp != null && x != null) { + Element status = packet.findChild("status"); + String msg = status != null ? status.getContent() : ""; + contact.setPgpKeyId(pgp.fetchKeyId(account, msg, x.getContent())); } boolean online = sizeBefore < contact.getPresences().size(); updateLastseen(packet, account, false); @@ -87,8 +86,7 @@ public class PresenceParser extends AbstractParser implements } else { contact.removePresence(from.getResourcepart()); } - mXmppConnectionService.onContactStatusChanged - .onContactStatusChanged(contact, false); + mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false); } else if (type.equals("subscribe")) { if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) { mXmppConnectionService.sendPresencePacket(account, @@ -97,25 +95,6 @@ public class PresenceParser extends AbstractParser implements contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST); } } - Element nick = packet.findChild("nick", - "http://jabber.org/protocol/nick"); - if (nick != null) { - contact.setPresenceName(nick.getContent()); - } - Element x = packet.findChild("x","vcard-temp:x:update"); - Avatar avatar = Avatar.parsePresence(x); - if (avatar != null && !contact.isSelf()) { - avatar.owner = from.toBareJid(); - if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { - if (contact.setAvatar(avatar)) { - mXmppConnectionService.getAvatarService().clear(contact); - mXmppConnectionService.updateConversationUi(); - mXmppConnectionService.updateRosterUi(); - } - } else { - mXmppConnectionService.fetchAvatar(account,avatar); - } - } mXmppConnectionService.updateRosterUi(); } -- cgit v1.2.3 From df86b0fc47cb7af8e97826f97d0e202405cff414 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 06:23:32 +0200 Subject: improved compatibility with muc components that change the message id --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 898613e3..fe42a2ae 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -269,9 +269,10 @@ public class MessageParser extends AbstractParser implements status = Message.STATUS_SEND; if (mXmppConnectionService.markMessage(conversation, remoteMsgId, Message.STATUS_SEND_RECEIVED)) { return; - } else if (remoteMsgId == null) { - Message message = conversation.findSentMessageWithBody(packet.getBody()); + } else { + Message message = conversation.findSentMessageWithBody(body); if (message != null) { + message.setRemoteMsgId(remoteMsgId); mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); return; } -- cgit v1.2.3 From 8ac933be9f8fddfda42159636d41c7652f7b79d6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 12:21:35 +0200 Subject: fixed more edge cases in muc message parser --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index fe42a2ae..bbb550b2 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -266,14 +266,14 @@ public class MessageParser extends AbstractParser implements Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { - status = Message.STATUS_SEND; - if (mXmppConnectionService.markMessage(conversation, remoteMsgId, Message.STATUS_SEND_RECEIVED)) { + status = Message.STATUS_SEND_RECEIVED; + if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) { return; } else { Message message = conversation.findSentMessageWithBody(body); if (message != null) { message.setRemoteMsgId(remoteMsgId); - mXmppConnectionService.markMessage(message, Message.STATUS_SEND_RECEIVED); + mXmppConnectionService.markMessage(message, status); return; } } -- cgit v1.2.3 From fe1cff016f3e1bccaf8287fb490380281cb13983 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 2 Jun 2015 13:33:20 +0200 Subject: avoid unnessary muc mam queries when message count is 0 after subject --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index bbb550b2..d0d517ee 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -367,7 +367,7 @@ public class MessageParser extends AbstractParser implements if (packet.hasChild("subject") && isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setHasMessagesLeftOnServer(true); + conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0); conversation.getMucOptions().setSubject(packet.findChildContent("subject")); mXmppConnectionService.updateConversationUi(); return; -- cgit v1.2.3 From 6b794eca2cfc8d1edf4f73c740a3e1b4e966da27 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 4 Jun 2015 02:47:24 +0200 Subject: send_received muc messages will mark a conversation a read --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d0d517ee..96568fbd 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -320,7 +320,7 @@ public class MessageParser extends AbstractParser implements } conversation.add(message); if (serverMsgId == null) { - if (status == Message.STATUS_SEND) { + if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) { mXmppConnectionService.markRead(conversation); account.activateGracePeriod(); } else { -- cgit v1.2.3 From 46595b6d43679f17cb8e374b2120ab7889423555 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Jun 2015 20:11:28 +0200 Subject: fixed parsing of muc status messages in new message parser --- .../siacs/conversations/parser/MessageParser.java | 24 ++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 96568fbd..946e4b6f 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -364,13 +364,25 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.getNotificationService().push(message); } } else { //no body - if (packet.hasChild("subject") && isTypeGroupChat) { + if (isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); - if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { - conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0); - conversation.getMucOptions().setSubject(packet.findChildContent("subject")); - mXmppConnectionService.updateConversationUi(); - return; + if (packet.hasChild("subject")) { + if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { + conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0); + conversation.getMucOptions().setSubject(packet.findChildContent("subject")); + mXmppConnectionService.updateConversationUi(); + return; + } + } + + final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); + if (conversation != null && x != null && from.isBareJid()) { + for (Element child : x.getChildren()) { + if (child.getName().equals("status") + && MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) { + mXmppConnectionService.fetchConferenceConfiguration(conversation); + } + } } } } -- cgit v1.2.3 From 0d01e51da5333cfbc3ac2cb0e381180823203e1b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 28 Jun 2015 22:14:40 +0200 Subject: don't parse body from muc status messages --- .../java/eu/siacs/conversations/parser/MessageParser.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 946e4b6f..5a40b170 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -233,13 +233,15 @@ public class MessageParser extends AbstractParser implements } final String body = packet.getBody(); final String encrypted = packet.findChildContent("x", "jabber:x:encrypted"); + final Element mucUserElement = packet.findChild("x","http://jabber.org/protocol/muc#user"); int status; final Jid counterpart; final Jid to = packet.getTo(); final Jid from = packet.getFrom(); final String remoteMsgId = packet.getId(); boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; - boolean properlyAddressed = !to.isBareJid() || account.countPresences() == 1; + boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1; + boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status"); if (packet.fromAccount(account)) { status = Message.STATUS_SEND; counterpart = to; @@ -262,7 +264,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.updateConversationUi(); } - if (body != null || encrypted != null) { + if ((body != null || encrypted != null) && !isMucStatusMessage) { Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { @@ -283,7 +285,7 @@ public class MessageParser extends AbstractParser implements } Message message; if (body != null && body.startsWith("?OTR")) { - if (!isForwarded && !isTypeGroupChat && properlyAddressed) { + if (!isForwarded && !isTypeGroupChat && isProperlyAddressed) { message = parseOtrChat(body, from, remoteMsgId, conversation); if (message == null) { return; @@ -375,9 +377,8 @@ public class MessageParser extends AbstractParser implements } } - final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); - if (conversation != null && x != null && from.isBareJid()) { - for (Element child : x.getChildren()) { + if (conversation != null && isMucStatusMessage) { + for (Element child : mucUserElement.getChildren()) { if (child.getName().equals("status") && MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) { mXmppConnectionService.fetchConferenceConfiguration(conversation); -- cgit v1.2.3 From d7de3113795738ada1488f673f6e7b651e166058 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 30 Jun 2015 13:52:53 +0200 Subject: refactored bodyContainsDownloadable to be more flexible --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 5a40b170..6d2aebf2 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -360,7 +360,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.databaseBackend.createMessage(message); } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); - if (message.trusted() && message.bodyContainsDownloadable() && manager.getAutoAcceptFileSize() > 0) { + if (message.trusted() && message.treatAsDownloadable() == Message.Decision.YES && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); -- cgit v1.2.3 From c20a088ea811ab702244006fa2588cbdf7be0099 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 1 Jul 2015 16:01:18 +0200 Subject: changed mime type 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/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 6d2aebf2..d1b8c03a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -360,7 +360,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.databaseBackend.createMessage(message); } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); - if (message.trusted() && message.treatAsDownloadable() == Message.Decision.YES && manager.getAutoAcceptFileSize() > 0) { + if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { manager.createNewConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); -- cgit v1.2.3 From a2525346f461183125c5840498228c347a86d4aa Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 2 Jul 2015 18:02:32 +0200 Subject: moved null check for to and from in message parser --- .../java/eu/siacs/conversations/parser/MessageParser.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d1b8c03a..72f822ca 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -239,6 +239,12 @@ public class MessageParser extends AbstractParser implements final Jid to = packet.getTo(); final Jid from = packet.getFrom(); final String remoteMsgId = packet.getId(); + + if (from == null || to == null) { + Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); + return; + } + boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1; boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status"); @@ -250,11 +256,6 @@ public class MessageParser extends AbstractParser implements counterpart = from; } - if (from == null || to == null) { - Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); - return; - } - Invite invite = extractInvite(packet); if (invite != null && invite.execute(account)) { return; -- cgit v1.2.3 From 78aff1329fa43b568e66fb1cf4fbf7356cfbeb3a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2015 15:14:13 +0200 Subject: renamed HttpConnection to HttpDownloadConnection --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 72f822ca..d46ff195 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -362,7 +362,7 @@ public class MessageParser extends AbstractParser implements } final HttpConnectionManager manager = this.mXmppConnectionService.getHttpConnectionManager(); if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { - manager.createNewConnection(message); + manager.createNewDownloadConnection(message); } else if (!message.isRead()) { mXmppConnectionService.getNotificationService().push(message); } -- cgit v1.2.3 From 77619b55e47aafbe6b5a530b33ce8b6a77a615dd Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 25 Jun 2015 16:58:24 +0200 Subject: Added PEP and message protocol layers Can now fetch/retrieve from PEP, as well as encode/decode messages --- .../eu/siacs/conversations/parser/IqParser.java | 158 ++++++++++++++++++++- .../siacs/conversations/parser/MessageParser.java | 46 +++++- 2 files changed, 197 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 6039d395..00f96885 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -1,9 +1,19 @@ package eu.siacs.conversations.parser; +import android.util.Base64; import android.util.Log; +import org.whispersystems.libaxolotl.IdentityKey; +import org.whispersystems.libaxolotl.InvalidKeyException; +import org.whispersystems.libaxolotl.ecc.Curve; +import org.whispersystems.libaxolotl.ecc.ECPublicKey; +import org.whispersystems.libaxolotl.state.PreKeyBundle; + import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; @@ -60,7 +70,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public String avatarData(final IqPacket packet) { final Element pubsub = packet.findChild("pubsub", - "http://jabber.org/protocol/pubsub"); + "http://jabber.org/protocol/pubsub"); if (pubsub == null) { return null; } @@ -71,6 +81,152 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return super.avatarData(items); } + public Element getItem(final IqPacket packet) { + final Element pubsub = packet.findChild("pubsub", + "http://jabber.org/protocol/pubsub"); + if (pubsub == null) { + return null; + } + final Element items = pubsub.findChild("items"); + if (items == null) { + return null; + } + return items.findChild("item"); + } + + public List deviceIds(final Element item) { + List deviceIds = new ArrayList<>(); + if (item == null) { + return null; + } + final Element list = item.findChild("list"); + if(list == null) { + return null; + } + for(Element device : list.getChildren()) { + if(!device.getName().equals("device")) { + continue; + } + try { + Integer id = Integer.valueOf(device.getAttribute("id")); + deviceIds.add(id); + } catch (NumberFormatException e) { + Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() + + ", skipping..."); + continue; + } + } + return deviceIds; + } + + public Integer signedPreKeyId(final Element bundle) { + final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic"); + if(signedPreKeyPublic == null) { + return null; + } + return Integer.valueOf(signedPreKeyPublic.getAttribute("signedPreKeyId")); + } + + public ECPublicKey signedPreKeyPublic(final Element bundle) { + ECPublicKey publicKey = null; + final Element signedPreKeyPublic = bundle.findChild("signedPreKeyPublic"); + if(signedPreKeyPublic == null) { + return null; + } + try { + publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0); + } catch (InvalidKeyException e) { + Log.e(Config.LOGTAG, "Invalid signedPreKeyPublic in PEP: " + e.getMessage()); + } + return publicKey; + } + + public byte[] signedPreKeySignature(final Element bundle) { + final Element signedPreKeySignature = bundle.findChild("signedPreKeySignature"); + if(signedPreKeySignature == null) { + return null; + } + return Base64.decode(signedPreKeySignature.getContent(),Base64.DEFAULT); + } + + public IdentityKey identityKey(final Element bundle) { + IdentityKey identityKey = null; + final Element identityKeyElement = bundle.findChild("identityKey"); + if(identityKeyElement == null) { + return null; + } + try { + identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0); + } catch (InvalidKeyException e) { + Log.e(Config.LOGTAG,"Invalid identityKey in PEP: "+e.getMessage()); + } + return identityKey; + } + + public Map preKeyPublics(final IqPacket packet) { + Map preKeyRecords = new HashMap<>(); + Element prekeysItem = getItem(packet); + if (prekeysItem == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } + final Element prekeysElement = prekeysItem.findChild("prekeys"); + if(prekeysElement == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } + for(Element preKeyPublicElement : prekeysElement.getChildren()) { + if(!preKeyPublicElement.getName().equals("preKeyPublic")){ + Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); + continue; + } + Integer preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId")); + try { + ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0); + preKeyRecords.put(preKeyId, preKeyPublic); + } catch (InvalidKeyException e) { + Log.e(Config.LOGTAG, "Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); + continue; + } + } + return preKeyRecords; + } + + public PreKeyBundle bundle(final IqPacket bundle) { + Element bundleItem = getItem(bundle); + if(bundleItem == null) { + return null; + } + final Element bundleElement = bundleItem.findChild("bundle"); + if(bundleElement == null) { + return null; + } + ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement); + Integer signedPreKeyId = signedPreKeyId(bundleElement); + byte[] signedPreKeySignature = signedPreKeySignature(bundleElement); + IdentityKey identityKey = identityKey(bundleElement); + if(signedPreKeyPublic == null || identityKey == null) { + return null; + } + + return new PreKeyBundle(0, 0, 0, null, + signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey); + } + + public List preKeys(final IqPacket preKeys) { + List bundles = new ArrayList<>(); + Map preKeyPublics = preKeyPublics(preKeys); + if ( preKeyPublics != null) { + for (Integer preKeyId : preKeyPublics.keySet()) { + ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId); + bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic, + 0, null, null, null)); + } + } + + return bundles; + } + @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d46ff195..bf4f3ad4 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -6,7 +6,11 @@ import android.util.Pair; import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; +import java.util.List; + 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.Contact; import eu.siacs.conversations.entities.Conversation; @@ -94,6 +98,18 @@ public class MessageParser extends AbstractParser implements } } + private Message parseAxolotlChat(Element axolotlMessage, Jid from, String id, Conversation conversation) { + Message finishedMessage = null; + AxolotlService service = conversation.getAccount().getAxolotlService(); + XmppAxolotlMessage xmppAxolotlMessage = new XmppAxolotlMessage(conversation.getContact(), axolotlMessage); + XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); + if(plaintextMessage != null) { + finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, Message.STATUS_RECEIVED); + } + + return finishedMessage; + } + private class Invite { Jid jid; String password; @@ -170,6 +186,18 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.updateConversationUi(); mXmppConnectionService.updateAccountUi(); } + } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) { + Log.d(Config.LOGTAG, "Received PEP device list update from "+ from + ", processing..."); + Element item = items.findChild("item"); + List deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); + AxolotlService axolotlService = account.getAxolotlService(); + if(account.getJid().toBareJid().equals(from)) { + } else { + Contact contact = account.getRoster().getContact(from); + for (Integer deviceId : deviceIds) { + axolotlService.fetchBundleIfNeeded(contact, deviceId); + } + } } } @@ -232,8 +260,9 @@ public class MessageParser extends AbstractParser implements timestamp = AbstractParser.getTimestamp(packet, System.currentTimeMillis()); } final String body = packet.getBody(); - final String encrypted = packet.findChildContent("x", "jabber:x:encrypted"); 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; final Jid counterpart; final Jid to = packet.getTo(); @@ -261,11 +290,11 @@ public class MessageParser extends AbstractParser implements return; } - if (extractChatState(mXmppConnectionService.find(account,from), packet)) { + if (extractChatState(mXmppConnectionService.find(account, from), packet)) { mXmppConnectionService.updateConversationUi(); } - if ((body != null || encrypted != null) && !isMucStatusMessage) { + if ((body != null || pgpEncrypted != null || axolotlEncrypted != null) && !isMucStatusMessage) { Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { @@ -294,9 +323,14 @@ public class MessageParser extends AbstractParser implements } else { message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } - } else if (encrypted != null) { - message = new Message(conversation, encrypted, Message.ENCRYPTION_PGP, status); - } else { + } else if (pgpEncrypted != null) { + message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status); + } else if (axolotlEncrypted != null) { + message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation); + if (message == null) { + return; + } + } else { message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } message.setCounterpart(counterpart); -- cgit v1.2.3 From 299bbdf27f0144e6eed99e70a3b2e46f9a3aa301 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 26 Jun 2015 15:41:02 +0200 Subject: Reformat code to use tabs This really sucks to do it like this. Sorry. :( --- .../eu/siacs/conversations/parser/IqParser.java | 76 +++++++++++----------- .../siacs/conversations/parser/MessageParser.java | 56 ++++++++-------- 2 files changed, 66 insertions(+), 66 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 00f96885..df143a41 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -70,7 +70,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public String avatarData(final IqPacket packet) { final Element pubsub = packet.findChild("pubsub", - "http://jabber.org/protocol/pubsub"); + "http://jabber.org/protocol/pubsub"); if (pubsub == null) { return null; } @@ -165,19 +165,19 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public Map preKeyPublics(final IqPacket packet) { Map preKeyRecords = new HashMap<>(); - Element prekeysItem = getItem(packet); - if (prekeysItem == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); - return null; - } - final Element prekeysElement = prekeysItem.findChild("prekeys"); - if(prekeysElement == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); - return null; - } + Element prekeysItem = getItem(packet); + if (prekeysItem == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } + final Element prekeysElement = prekeysItem.findChild("prekeys"); + if(prekeysElement == null) { + Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + return null; + } for(Element preKeyPublicElement : prekeysElement.getChildren()) { if(!preKeyPublicElement.getName().equals("preKeyPublic")){ - Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); + Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); continue; } Integer preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId")); @@ -192,37 +192,37 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return preKeyRecords; } - public PreKeyBundle bundle(final IqPacket bundle) { - Element bundleItem = getItem(bundle); - if(bundleItem == null) { - return null; - } - final Element bundleElement = bundleItem.findChild("bundle"); - if(bundleElement == null) { - return null; - } - ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement); - Integer signedPreKeyId = signedPreKeyId(bundleElement); - byte[] signedPreKeySignature = signedPreKeySignature(bundleElement); - IdentityKey identityKey = identityKey(bundleElement); - if(signedPreKeyPublic == null || identityKey == null) { - return null; - } + public PreKeyBundle bundle(final IqPacket bundle) { + Element bundleItem = getItem(bundle); + if(bundleItem == null) { + return null; + } + final Element bundleElement = bundleItem.findChild("bundle"); + if(bundleElement == null) { + return null; + } + ECPublicKey signedPreKeyPublic = signedPreKeyPublic(bundleElement); + Integer signedPreKeyId = signedPreKeyId(bundleElement); + byte[] signedPreKeySignature = signedPreKeySignature(bundleElement); + IdentityKey identityKey = identityKey(bundleElement); + if(signedPreKeyPublic == null || identityKey == null) { + return null; + } - return new PreKeyBundle(0, 0, 0, null, - signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey); - } + return new PreKeyBundle(0, 0, 0, null, + signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey); + } public List preKeys(final IqPacket preKeys) { List bundles = new ArrayList<>(); Map preKeyPublics = preKeyPublics(preKeys); - if ( preKeyPublics != null) { - for (Integer preKeyId : preKeyPublics.keySet()) { - ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId); - bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic, - 0, null, null, null)); - } - } + if ( preKeyPublics != null) { + for (Integer preKeyId : preKeyPublics.keySet()) { + ECPublicKey preKeyPublic = preKeyPublics.get(preKeyId); + bundles.add(new PreKeyBundle(0, 0, preKeyId, preKeyPublic, + 0, null, null, null)); + } + } return bundles; } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index bf4f3ad4..de705730 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -98,17 +98,17 @@ public class MessageParser extends AbstractParser implements } } - private Message parseAxolotlChat(Element axolotlMessage, Jid from, String id, Conversation conversation) { - Message finishedMessage = null; - AxolotlService service = conversation.getAccount().getAxolotlService(); - XmppAxolotlMessage xmppAxolotlMessage = new XmppAxolotlMessage(conversation.getContact(), axolotlMessage); - XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); - if(plaintextMessage != null) { - finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, Message.STATUS_RECEIVED); - } + private Message parseAxolotlChat(Element axolotlMessage, Jid from, String id, Conversation conversation) { + Message finishedMessage = null; + AxolotlService service = conversation.getAccount().getAxolotlService(); + XmppAxolotlMessage xmppAxolotlMessage = new XmppAxolotlMessage(conversation.getContact(), axolotlMessage); + XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); + if(plaintextMessage != null) { + finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, Message.STATUS_RECEIVED); + } - return finishedMessage; - } + return finishedMessage; + } private class Invite { Jid jid; @@ -187,17 +187,17 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.updateAccountUi(); } } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) { - Log.d(Config.LOGTAG, "Received PEP device list update from "+ from + ", processing..."); - Element item = items.findChild("item"); + Log.d(Config.LOGTAG, "Received PEP device list update from "+ from + ", processing..."); + Element item = items.findChild("item"); List deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); - AxolotlService axolotlService = account.getAxolotlService(); - if(account.getJid().toBareJid().equals(from)) { - } else { - Contact contact = account.getRoster().getContact(from); - for (Integer deviceId : deviceIds) { - axolotlService.fetchBundleIfNeeded(contact, deviceId); - } - } + AxolotlService axolotlService = account.getAxolotlService(); + if(account.getJid().toBareJid().equals(from)) { + } else { + Contact contact = account.getRoster().getContact(from); + for (Integer deviceId : deviceIds) { + axolotlService.fetchBundleIfNeeded(contact, deviceId); + } + } } } @@ -262,7 +262,7 @@ public class MessageParser extends AbstractParser implements final String body = packet.getBody(); 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); + final Element axolotlEncrypted = packet.findChild("axolotl_message", AxolotlService.PEP_PREFIX); int status; final Jid counterpart; final Jid to = packet.getTo(); @@ -324,13 +324,13 @@ public class MessageParser extends AbstractParser implements message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } } else if (pgpEncrypted != null) { - message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status); - } else if (axolotlEncrypted != null) { - message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation); - if (message == null) { - return; - } - } else { + message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status); + } else if (axolotlEncrypted != null) { + message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation); + if (message == null) { + return; + } + } else { message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } message.setCounterpart(counterpart); -- cgit v1.2.3 From c1d23b2395bfc9570aed07ba3413f988f08d84f5 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 29 Jun 2015 14:18:11 +0200 Subject: Migrate to new PEP layout Merge prekeys into bundle node --- .../java/eu/siacs/conversations/parser/IqParser.java | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index df143a41..93551787 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -12,8 +12,10 @@ import org.whispersystems.libaxolotl.state.PreKeyBundle; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; @@ -94,8 +96,8 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return items.findChild("item"); } - public List deviceIds(final Element item) { - List deviceIds = new ArrayList<>(); + public Set deviceIds(final Element item) { + Set deviceIds = new HashSet<>(); if (item == null) { return null; } @@ -165,14 +167,18 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { public Map preKeyPublics(final IqPacket packet) { Map preKeyRecords = new HashMap<>(); - Element prekeysItem = getItem(packet); - if (prekeysItem == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + Element item = getItem(packet); + if (item == null) { + Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); + return null; + } + final Element bundleElement = item.findChild("bundle"); + if(bundleElement == null) { return null; } - final Element prekeysElement = prekeysItem.findChild("prekeys"); + final Element prekeysElement = bundleElement.findChild("prekeys"); if(prekeysElement == null) { - Log.d(Config.LOGTAG, "Couldn't find in preKeyPublic IQ packet: " + packet); + Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); return null; } for(Element preKeyPublicElement : prekeysElement.getChildren()) { -- cgit v1.2.3 From 3815d4efa378846c8aef840ad659268a0bef1536 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 29 Jun 2015 14:22:26 +0200 Subject: Fetch bundles on-demand, encrypt in background Bundles are now fetched on demand when a session needs to be established. This should lessen the chance of changes to the bundles occuring before they're used, as well as lessen the load of fetching bundles. Also, the message encryption is now done in a background thread, as this can be somewhat costly if many sessions are present. This is probably not going to be an issue in real use, but it's good practice anyway. --- .../java/eu/siacs/conversations/parser/MessageParser.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index de705730..31f70b97 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -7,6 +7,7 @@ import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; import java.util.List; +import java.util.Set; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.AxolotlService; @@ -105,6 +106,7 @@ public class MessageParser extends AbstractParser implements XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); if(plaintextMessage != null) { finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, Message.STATUS_RECEIVED); + finishedMessage.setAxolotlSession(plaintextMessage.getSession()); } return finishedMessage; @@ -189,15 +191,9 @@ public class MessageParser extends AbstractParser implements } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) { Log.d(Config.LOGTAG, "Received PEP device list update from "+ from + ", processing..."); Element item = items.findChild("item"); - List deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); + Set deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); AxolotlService axolotlService = account.getAxolotlService(); - if(account.getJid().toBareJid().equals(from)) { - } else { - Contact contact = account.getRoster().getContact(from); - for (Integer deviceId : deviceIds) { - axolotlService.fetchBundleIfNeeded(contact, deviceId); - } - } + axolotlService.registerDevices(from, deviceIds); } } -- cgit v1.2.3 From ec6870307e0ecee8184ddfef73444290e9d15828 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 3 Jul 2015 13:27:35 +0200 Subject: Properly track message sender Previously, the sender was assumed to be the conversation counterpart. This broke carboned own-device messages. We now track the sender properly, and also set the status (sent by one of the own devices vs received from the counterpart) accordingly. --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 31f70b97..cc878e7f 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -99,13 +99,13 @@ public class MessageParser extends AbstractParser implements } } - private Message parseAxolotlChat(Element axolotlMessage, Jid from, String id, Conversation conversation) { + private Message parseAxolotlChat(Element axolotlMessage, Jid from, String id, Conversation conversation, int status) { Message finishedMessage = null; AxolotlService service = conversation.getAccount().getAxolotlService(); - XmppAxolotlMessage xmppAxolotlMessage = new XmppAxolotlMessage(conversation.getContact(), axolotlMessage); + XmppAxolotlMessage xmppAxolotlMessage = new XmppAxolotlMessage(from.toBareJid(), axolotlMessage); XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); if(plaintextMessage != null) { - finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, Message.STATUS_RECEIVED); + finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, status); finishedMessage.setAxolotlSession(plaintextMessage.getSession()); } @@ -322,7 +322,7 @@ public class MessageParser extends AbstractParser implements } else if (pgpEncrypted != null) { message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status); } else if (axolotlEncrypted != null) { - message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation); + message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation, status); if (message == null) { return; } -- cgit v1.2.3 From 6867b5c3abeeb5116a2542c56a706b733fd9cbf0 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sun, 5 Jul 2015 22:53:34 +0200 Subject: Return empty set on invalid PEP devicelist --- .../eu/siacs/conversations/parser/IqParser.java | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 93551787..c147978e 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.parser; +import android.support.annotation.NonNull; import android.util.Base64; import android.util.Log; @@ -96,26 +97,25 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return items.findChild("item"); } + @NonNull public Set deviceIds(final Element item) { Set deviceIds = new HashSet<>(); - if (item == null) { - return null; - } - final Element list = item.findChild("list"); - if(list == null) { - return null; - } - for(Element device : list.getChildren()) { - if(!device.getName().equals("device")) { - continue; - } - try { - Integer id = Integer.valueOf(device.getAttribute("id")); - deviceIds.add(id); - } catch (NumberFormatException e) { - Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() - + ", skipping..."); - continue; + if (item != null) { + final Element list = item.findChild("list"); + if (list != null) { + for (Element device : list.getChildren()) { + if (!device.getName().equals("device")) { + continue; + } + try { + Integer id = Integer.valueOf(device.getAttribute("id")); + deviceIds.add(id); + } catch (NumberFormatException e) { + Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() + + ", skipping..."); + continue; + } + } } } return deviceIds; -- cgit v1.2.3 From 968410ae33f7ed341868847f3fedbd03ebd54f2b Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 7 Jul 2015 19:32:52 +0200 Subject: Fix devicelist update handling No longer store own device ID (so that we don't encrypt messages for ourselves), verify that own device ID is present in update list (otherwise republish), reflect update in UI. --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index cc878e7f..0dc8d521 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -194,6 +194,7 @@ public class MessageParser extends AbstractParser implements Set deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); AxolotlService axolotlService = account.getAxolotlService(); axolotlService.registerDevices(from, deviceIds); + mXmppConnectionService.updateAccountUi(); } } -- cgit v1.2.3 From 3458f5bb9182ca99dd800e4cde21168323260da4 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 8 Jul 2015 17:44:24 +0200 Subject: Clean up logging Add a fixed prefix to axolotl-related log messages, set log levels sensibly. --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 15 ++++++++------- .../java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index c147978e..e74cb65c 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Set; import eu.siacs.conversations.Config; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.services.XmppConnectionService; @@ -111,7 +112,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { Integer id = Integer.valueOf(device.getAttribute("id")); deviceIds.add(id); } catch (NumberFormatException e) { - Log.e(Config.LOGTAG, "Encountered nvalid node in PEP:" + device.toString() + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered nvalid node in PEP:" + device.toString() + ", skipping..."); continue; } @@ -138,7 +139,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { try { publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0); } catch (InvalidKeyException e) { - Log.e(Config.LOGTAG, "Invalid signedPreKeyPublic in PEP: " + e.getMessage()); + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid signedPreKeyPublic in PEP: " + e.getMessage()); } return publicKey; } @@ -160,7 +161,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { try { identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0); } catch (InvalidKeyException e) { - Log.e(Config.LOGTAG,"Invalid identityKey in PEP: "+e.getMessage()); + Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : "+"Invalid identityKey in PEP: "+e.getMessage()); } return identityKey; } @@ -169,7 +170,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { Map preKeyRecords = new HashMap<>(); Element item = getItem(packet); if (item == null) { - Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Couldn't find in bundle IQ packet: " + packet); return null; } final Element bundleElement = item.findChild("bundle"); @@ -178,12 +179,12 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } final Element prekeysElement = bundleElement.findChild("prekeys"); if(prekeysElement == null) { - Log.d(Config.LOGTAG, "Couldn't find in bundle IQ packet: " + packet); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Couldn't find in bundle IQ packet: " + packet); return null; } for(Element preKeyPublicElement : prekeysElement.getChildren()) { if(!preKeyPublicElement.getName().equals("preKeyPublic")){ - Log.d(Config.LOGTAG, "Encountered unexpected tag in prekeys list: " + preKeyPublicElement); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered unexpected tag in prekeys list: " + preKeyPublicElement); continue; } Integer preKeyId = Integer.valueOf(preKeyPublicElement.getAttribute("preKeyId")); @@ -191,7 +192,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0); preKeyRecords.put(preKeyId, preKeyPublic); } catch (InvalidKeyException e) { - Log.e(Config.LOGTAG, "Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); continue; } } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 0dc8d521..8b5f97af 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -189,7 +189,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.updateAccountUi(); } } else if (AxolotlService.PEP_DEVICE_LIST.equals(node)) { - Log.d(Config.LOGTAG, "Received PEP device list update from "+ from + ", processing..."); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Received PEP device list update from "+ from + ", processing..."); Element item = items.findChild("item"); Set deviceIds = mXmppConnectionService.getIqParser().deviceIds(item); AxolotlService axolotlService = account.getAxolotlService(); -- cgit v1.2.3 From d173913ebabbf8de2725dd296ae6428defd4b3b3 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 9 Jul 2015 14:23:17 +0200 Subject: Overhauled Message tagging Messages are now tagged with the IdentityKey fingerprint of the originating session. IdentityKeys have one of three trust states: undecided (default), trusted, and untrusted/not yet trusted. --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 8b5f97af..9cbe5b46 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -106,7 +106,8 @@ public class MessageParser extends AbstractParser implements XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); if(plaintextMessage != null) { finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, status); - finishedMessage.setAxolotlSession(plaintextMessage.getSession()); + finishedMessage.setAxolotlFingerprint(plaintextMessage.getFingerprint()); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(finishedMessage.getConversation().getAccount())+" Received Message with session fingerprint: "+plaintextMessage.getFingerprint()); } return finishedMessage; -- cgit v1.2.3 From 012f036840ade8f46462eafcc96d1f223f8ba845 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 14:26:29 +0200 Subject: Optimize imports --- src/main/java/eu/siacs/conversations/parser/AbstractParser.java | 1 - src/main/java/eu/siacs/conversations/parser/MessageParser.java | 1 - 2 files changed, 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index 24e93db1..18331796 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -11,7 +11,6 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.Jid; -import eu.siacs.conversations.xmpp.stanzas.MessagePacket; public abstract class AbstractParser { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 9cbe5b46..38e0f98a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -6,7 +6,6 @@ import android.util.Pair; import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; -import java.util.List; import java.util.Set; import eu.siacs.conversations.Config; -- 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/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 38e0f98a..0d0dce49 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 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/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 0d0dce49..b81a62da 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 f1ee5cccf0b26e2b533d3ce85a020ba8f2a03b8a 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/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d46ff195..97bacd8c 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -66,18 +66,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 af76ad01444cc485fcaa67be534278008675c9bb 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/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 97bacd8c..94073f8a 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -177,7 +177,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 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/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index b81a62da..c2fdf5b8 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 d38228f4829fe427b315e1f5c6be47542729549b 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/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 94073f8a..2d722af7 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -181,7 +181,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 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) --- .../eu/siacs/conversations/parser/MessageParser.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index c2fdf5b8..6e7b3276 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 6b8e1ecb9532509ac6bca6ca3665f6ac3f560332 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 28 Jul 2015 14:44:11 +0200 Subject: log reason for message failure --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 6e7b3276..f0659511 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -202,6 +202,13 @@ public class MessageParser extends AbstractParser implements if (packet.getType() == MessagePacket.TYPE_ERROR) { Jid from = packet.getFrom(); if (from != null) { + Element error = packet.findChild("error"); + String text = error == null ? null : error.findChildContent("text"); + if (text != null) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending message to "+ from+ " failed - " + text); + } else if (error != null) { + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": sending message to "+ from+ " failed - " + error); + } Message message = mXmppConnectionService.markMessage(account, from.toBareJid(), packet.getId(), -- cgit v1.2.3 From e6df4d81d23e4b7c0c3798f114714dd3caebfe8c Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 29 Jul 2015 16:41:58 +0200 Subject: Tag carbon messages in parser, adapt session logic Messages sent from another device of the own account are now explicitly tagged as carboned message. The session detection logic now uses this tag to find "session borders". --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index f0659511..3aaa3ce7 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -230,6 +230,7 @@ public class MessageParser extends AbstractParser implements final MessagePacket packet; Long timestamp = null; final boolean isForwarded; + boolean isCarbon = false; String serverMsgId = null; final Element fin = original.findChild("fin", "urn:xmpp:mam:0"); if (fin != null) { @@ -260,7 +261,8 @@ public class MessageParser extends AbstractParser implements return; } timestamp = f != null ? f.second : null; - isForwarded = f != null; + isCarbon = f != null; + isForwarded = isCarbon; } else { packet = original; isForwarded = false; @@ -346,6 +348,7 @@ public class MessageParser extends AbstractParser implements message.setCounterpart(counterpart); message.setRemoteMsgId(remoteMsgId); message.setServerMsgId(serverMsgId); + message.setCarbon(isCarbon); message.setTime(timestamp); message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); if (conversation.getMode() == Conversation.MODE_MULTI) { -- cgit v1.2.3 From 658919f239e9c816f958d17df9ba5ee79b6549b2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 31 Jul 2015 00:52:46 +0200 Subject: improved 'next encryption' selection --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 3aaa3ce7..4bee34a9 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -73,11 +73,9 @@ public class MessageParser extends AbstractParser implements body = otrSession.transformReceiving(body); SessionStatus status = otrSession.getSessionStatus(); if (body == null && status == SessionStatus.ENCRYPTED) { - conversation.setNextEncryption(Message.ENCRYPTION_OTR); mXmppConnectionService.onOtrSessionEstablished(conversation); return null; } else if (body == null && status == SessionStatus.FINISHED) { - conversation.setNextEncryption(Message.ENCRYPTION_NONE); conversation.resetOtrSession(); mXmppConnectionService.updateConversationUi(); return null; -- cgit v1.2.3 From 5c421da1e1bd4c6008c36b17569c3dbc5d5e918b Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 31 Jul 2015 17:59:41 +0200 Subject: Change to new wire protocol version --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 4bee34a9..47c320f3 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -272,7 +272,7 @@ public class MessageParser extends AbstractParser implements final String body = packet.getBody(); 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); + final Element axolotlEncrypted = packet.findChild(XmppAxolotlMessage.TAGNAME, AxolotlService.PEP_PREFIX); int status; final Jid counterpart; final Jid to = packet.getTo(); -- cgit v1.2.3 From 909f761ca1659938cf5f9d7206ee24d54faa8550 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 31 Jul 2015 21:12:34 +0200 Subject: Refactor axolotl message processing workflow XmppAxolotlMessage is now entirely responsible for handling encryption and decryption of messages, only leveraging XmppAxolotlSession as a packing/unpacking primitive for payload keys. Removed pseudo-dead session generation code step from prepareMessage function, as sessions have been created by invoking the TrustKeysActivity for a while now. Added prepareKeyTransportMessage function, which creates a message with no payload. The key that is packed into the header keyElements can then be used for other purposes (e.g. encrypted file transfer). --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 47c320f3..a53e3a50 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -99,7 +99,7 @@ public class MessageParser extends AbstractParser implements private Message parseAxolotlChat(Element axolotlMessage, Jid from, String id, Conversation conversation, int status) { Message finishedMessage = null; AxolotlService service = conversation.getAccount().getAxolotlService(); - XmppAxolotlMessage xmppAxolotlMessage = new XmppAxolotlMessage(from.toBareJid(), axolotlMessage); + XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlMessage, from.toBareJid()); XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); if(plaintextMessage != null) { finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, status); @@ -272,7 +272,7 @@ public class MessageParser extends AbstractParser implements final String body = packet.getBody(); 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(XmppAxolotlMessage.TAGNAME, AxolotlService.PEP_PREFIX); + final Element axolotlEncrypted = packet.findChild(XmppAxolotlMessage.CONTAINERTAG, AxolotlService.PEP_PREFIX); int status; final Jid counterpart; final Jid to = packet.getTo(); -- cgit v1.2.3 From 6059b964569fb406bbc86a0ccb19e76851fba2b6 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 31 Jul 2015 23:28:09 +0200 Subject: Provide process function for key transport message --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index a53e3a50..5786487f 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -100,7 +100,7 @@ public class MessageParser extends AbstractParser implements Message finishedMessage = null; AxolotlService service = conversation.getAccount().getAxolotlService(); XmppAxolotlMessage xmppAxolotlMessage = XmppAxolotlMessage.fromElement(axolotlMessage, from.toBareJid()); - XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceiving(xmppAxolotlMessage); + XmppAxolotlMessage.XmppAxolotlPlaintextMessage plaintextMessage = service.processReceivingPayloadMessage(xmppAxolotlMessage); if(plaintextMessage != null) { finishedMessage = new Message(conversation, plaintextMessage.getPlaintext(), Message.ENCRYPTION_AXOLOTL, status); finishedMessage.setAxolotlFingerprint(plaintextMessage.getFingerprint()); -- cgit v1.2.3 From 496f531e2ef2cad5ff4dfb01ef0afe87c8b6b5c3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 23 Aug 2015 08:01:47 +0200 Subject: modified clearIqCallbacks into 2-step process --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index e74cb65c..4488eed8 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -236,7 +236,9 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { + if (packet.getType() == IqPacket.TYPE.ERROR) { + return; + } else if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { final Element query = packet.findChild("query"); // If this is in response to a query for the whole roster: if (packet.getType() == IqPacket.TYPE.RESULT) { @@ -306,15 +308,13 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT); mXmppConnectionService.sendIqPacket(account, response, null); } else { - if ((packet.getType() == IqPacket.TYPE.GET) - || (packet.getType() == IqPacket.TYPE.SET)) { + if (packet.getType() == IqPacket.TYPE.GET || packet.getType() == IqPacket.TYPE.SET) { final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR); final Element error = response.addChild("error"); error.setAttribute("type", "cancel"); - error.addChild("feature-not-implemented", - "urn:ietf:params:xml:ns:xmpp-stanzas"); + error.addChild("feature-not-implemented","urn:ietf:params:xml:ns:xmpp-stanzas"); account.getXmppConnection().sendIqPacket(response, null); - } + } } } -- cgit v1.2.3 From 0dfb9bd1a06436ffb6dd7a5cfbdefa11d3ae130e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 23 Aug 2015 17:53:23 +0200 Subject: introduce special iq type for internal timeouts. always use != result to check for error in callbacks --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 4488eed8..cef5b03d 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -236,7 +236,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { - if (packet.getType() == IqPacket.TYPE.ERROR) { + if (packet.getType() == IqPacket.TYPE.ERROR || packet.getType() == IqPacket.TYPE.TIMEOUT) { return; } else if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { final Element query = packet.findChild("query"); -- cgit v1.2.3 From d0b8bd0f8a0cb10c93d45d6900ff1fdb62db80b7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 24 Aug 2015 18:18:01 +0200 Subject: catch invalid base64 in axolotl key parsing --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index cef5b03d..44e4bc08 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -138,7 +138,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } try { publicKey = Curve.decodePoint(Base64.decode(signedPreKeyPublic.getContent(),Base64.DEFAULT), 0); - } catch (InvalidKeyException e) { + } catch (InvalidKeyException | IllegalArgumentException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid signedPreKeyPublic in PEP: " + e.getMessage()); } return publicKey; -- cgit v1.2.3 From 3e0636367a733285526c709138110ddb86899196 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 26 Aug 2015 11:39:18 +0200 Subject: Revert "improved compatibility with muc components that change the message id" This reverts commit df86b0fc47cb7af8e97826f97d0e202405cff414. --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 025ed1e7..ec900de4 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -311,10 +311,9 @@ public class MessageParser extends AbstractParser implements status = Message.STATUS_SEND_RECEIVED; if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) { return; - } else { - Message message = conversation.findSentMessageWithBody(body); + } else if (remoteMsgId == null) { + Message message = conversation.findSentMessageWithBody(packet.getBody()); if (message != null) { - message.setRemoteMsgId(remoteMsgId); mXmppConnectionService.markMessage(message, status); return; } -- cgit v1.2.3 From 8f4b7686c94c52563c29f100cd25599ac08a7bb2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 30 Aug 2015 11:11:54 +0200 Subject: catch invalid base64 on omemo key decoding --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index 44e4bc08..f6446cfd 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -149,7 +149,12 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { if(signedPreKeySignature == null) { return null; } - return Base64.decode(signedPreKeySignature.getContent(),Base64.DEFAULT); + try { + return Base64.decode(signedPreKeySignature.getContent(), Base64.DEFAULT); + } catch (IllegalArgumentException e) { + Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : Invalid base64 in signedPreKeySignature"); + return null; + } } public IdentityKey identityKey(final Element bundle) { @@ -160,7 +165,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } try { identityKey = new IdentityKey(Base64.decode(identityKeyElement.getContent(), Base64.DEFAULT), 0); - } catch (InvalidKeyException e) { + } catch (InvalidKeyException | IllegalArgumentException e) { Log.e(Config.LOGTAG,AxolotlService.LOGPREFIX+" : "+"Invalid identityKey in PEP: "+e.getMessage()); } return identityKey; @@ -191,7 +196,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { try { ECPublicKey preKeyPublic = Curve.decodePoint(Base64.decode(preKeyPublicElement.getContent(), Base64.DEFAULT), 0); preKeyRecords.put(preKeyId, preKeyPublic); - } catch (InvalidKeyException e) { + } catch (InvalidKeyException | IllegalArgumentException e) { Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Invalid preKeyPublic (ID="+preKeyId+") in PEP: "+ e.getMessage()+", skipping..."); continue; } -- cgit v1.2.3 From e6af5020555a2b19a5038647c7f55221fc8a4739 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 6 Oct 2015 11:44:27 +0200 Subject: clear notification and activate grace period when receiving chat marker from another instance --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index ec900de4..4d057756 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -40,6 +40,10 @@ public class MessageParser extends AbstractParser implements Jid from = packet.getFrom(); if (from.toBareJid().equals(account.getJid().toBareJid())) { conversation.setOutgoingChatState(state); + if (state == ChatState.ACTIVE || state == ChatState.COMPOSING) { + mXmppConnectionService.markRead(conversation); + account.activateGracePeriod(); + } return false; } else { return conversation.setIncomingChatState(state); @@ -300,7 +304,7 @@ public class MessageParser extends AbstractParser implements return; } - if (extractChatState(mXmppConnectionService.find(account, from), packet)) { + if (extractChatState(mXmppConnectionService.find(account, counterpart.toBareJid()), packet)) { mXmppConnectionService.updateConversationUi(); } -- cgit v1.2.3 From 0587ba2ad274907ecc35f7fb38cc9e919af93d2a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 14 Oct 2015 11:15:18 +0200 Subject: work with muc services that change the message id --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 4d057756..c53e50ac 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -315,7 +315,7 @@ public class MessageParser extends AbstractParser implements status = Message.STATUS_SEND_RECEIVED; if (mXmppConnectionService.markMessage(conversation, remoteMsgId, status)) { return; - } else if (remoteMsgId == null) { + } else if (remoteMsgId == null || Config.IGNORE_ID_REWRITE_IN_MUC) { Message message = conversation.findSentMessageWithBody(packet.getBody()); if (message != null) { mXmppConnectionService.markMessage(message, status); -- cgit v1.2.3 From cfeb67d71da01bc95ed713d6591fa6e79fc08dd6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 16 Oct 2015 23:48:42 +0200 Subject: introduced code to verify omemo device keys with x509 certificates. cleaned up TrustKeysActivity to automatically close if there is nothing to do --- .../eu/siacs/conversations/parser/IqParser.java | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index f6446cfd..e26a493f 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.parser; import android.support.annotation.NonNull; import android.util.Base64; import android.util.Log; +import android.util.Pair; import org.whispersystems.libaxolotl.IdentityKey; import org.whispersystems.libaxolotl.InvalidKeyException; @@ -10,6 +11,10 @@ import org.whispersystems.libaxolotl.ecc.Curve; import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.state.PreKeyBundle; +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -204,6 +209,30 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { return preKeyRecords; } + public Pair verification(final IqPacket packet) { + Element item = getItem(packet); + Element verification = item != null ? item.findChild("verification",AxolotlService.PEP_PREFIX) : null; + Element chain = verification != null ? verification.findChild("chain") : null; + Element signature = verification != null ? verification.findChild("signature") : null; + if (chain != null && signature != null) { + List certElements = chain.getChildren(); + X509Certificate[] certificates = new X509Certificate[certElements.size()]; + try { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + int i = 0; + for(Element cert : certElements) { + certificates[i] = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(Base64.decode(cert.getContent(),Base64.DEFAULT))); + ++i; + } + return new Pair<>(certificates,Base64.decode(signature.getContent(),Base64.DEFAULT)); + } catch (CertificateException e) { + return null; + } + } else { + return null; + } + } + public PreKeyBundle bundle(final IqPacket bundle) { Element bundleItem = getItem(bundle); if(bundleItem == null) { -- cgit v1.2.3 From 9b07059b6e9c85935031ffc03e5e6d00a9376d57 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 19 Oct 2015 23:20:33 +0200 Subject: update last seen in mucs. fixes #1508 --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index c53e50ac..e39df085 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -353,7 +353,11 @@ public class MessageParser extends AbstractParser implements message.setTime(timestamp); message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); if (conversation.getMode() == Conversation.MODE_MULTI) { - message.setTrueCounterpart(conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart())); + Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart()); + message.setTrueCounterpart(trueCounterpart); + if (trueCounterpart != null) { + updateLastseen(packet,account,trueCounterpart,false); + } if (!isTypeGroupChat) { message.setType(Message.TYPE_PRIVATE); } -- cgit v1.2.3 From 29a849cb92c0dc902acd3aa54d0d2f07583bce72 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Thu, 15 Oct 2015 23:21:47 +0100 Subject: Decrypt PGP messages in background --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index e39df085..c534a417 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.parser; import android.util.Log; import android.util.Pair; +import eu.siacs.conversations.crypto.PgpDecryptionService; import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; @@ -114,6 +115,13 @@ public class MessageParser extends AbstractParser implements return finishedMessage; } + private Message parsePGPChat(final Conversation conversation, String pgpEncrypted, int status) { + final Message message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status); + PgpDecryptionService pgpDecryptionService = conversation.getAccount().getPgpDecryptionService(); + pgpDecryptionService.add(message); + return message; + } + private class Invite { Jid jid; String password; @@ -337,7 +345,7 @@ public class MessageParser extends AbstractParser implements message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } } else if (pgpEncrypted != null) { - message = new Message(conversation, pgpEncrypted, Message.ENCRYPTION_PGP, status); + message = parsePGPChat(conversation, pgpEncrypted, status); } else if (axolotlEncrypted != null) { message = parseAxolotlChat(axolotlEncrypted, from, remoteMsgId, conversation, status); if (message == null) { -- cgit v1.2.3 From c7ff196f58b5576ca1aeb5fd6d51bbe500754f06 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 29 Oct 2015 13:41:08 +0100 Subject: push CN into nick pep node when uploading certificate. subscribe to nick node --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index e39df085..05c23593 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -183,7 +183,7 @@ public class MessageParser extends AbstractParser implements } else if ("http://jabber.org/protocol/nick".equals(node)) { Element i = items.findChild("item"); Element nick = i == null ? null : i.findChild("nick", "http://jabber.org/protocol/nick"); - if (nick != null) { + if (nick != null && nick.getContent() != null) { Contact contact = account.getRoster().getContact(from); contact.setPresenceName(nick.getContent()); mXmppConnectionService.getAvatarService().clear(account); -- cgit v1.2.3 From d42c82abf21d92ae1e8c7d12510d376800a2b363 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 1 Dec 2015 12:22:47 +0100 Subject: combine multiple message receipts into single message --- .../java/eu/siacs/conversations/parser/MessageParser.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 58ca5135..b4c648fe 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -7,6 +7,7 @@ import eu.siacs.conversations.crypto.PgpDecryptionService; import net.java.otr4j.session.Session; import net.java.otr4j.session.SessionStatus; +import java.util.ArrayList; import java.util.Set; import eu.siacs.conversations.Config; @@ -393,17 +394,17 @@ public class MessageParser extends AbstractParser implements } if (mXmppConnectionService.confirmMessages() && remoteMsgId != null && !isForwarded && !isTypeGroupChat) { + ArrayList receiptsNamespaces = new ArrayList<>(); if (packet.hasChild("markable", "urn:xmpp:chat-markers:0")) { - MessagePacket receipt = mXmppConnectionService.getMessageGenerator().received(account, - packet, - "urn:xmpp:chat-markers:0", - MessagePacket.TYPE_CHAT); - mXmppConnectionService.sendMessagePacket(account, receipt); + receiptsNamespaces.add("urn:xmpp:chat-markers:0"); } if (packet.hasChild("request", "urn:xmpp:receipts")) { + receiptsNamespaces.add("urn:xmpp:receipts"); + } + if (receiptsNamespaces.size() > 0) { MessagePacket receipt = mXmppConnectionService.getMessageGenerator().received(account, packet, - "urn:xmpp:receipts", + receiptsNamespaces, packet.getType()); mXmppConnectionService.sendMessagePacket(account, receipt); } -- cgit v1.2.3 From a3eb540f059f9123799c54d69201eba8a096e116 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Wed, 4 Nov 2015 20:56:45 -0600 Subject: Show status message when contact requests presence Remove presence when conversation closed --- .../eu/siacs/conversations/parser/PresenceParser.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index d83347d8..59b94bc0 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -6,6 +6,7 @@ import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.MucOptions; import eu.siacs.conversations.entities.Presences; import eu.siacs.conversations.generator.PresenceGenerator; @@ -44,8 +45,8 @@ public class PresenceParser extends AbstractParser implements } } - public void parseContactPresence(PresencePacket packet, Account account) { - PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator(); + public void parseContactPresence(final PresencePacket packet, final Account account) { + final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator(); final Jid from = packet.getFrom(); if (from == null) { return; @@ -93,6 +94,17 @@ public class PresenceParser extends AbstractParser implements mPresenceGenerator.sendPresenceUpdatesTo(contact)); } else { contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST); + final String statusMessage = packet.findChildContent("status"); + if (statusMessage != null && !statusMessage.isEmpty()) { + final Conversation conversation = mXmppConnectionService.findOrCreateConversation( + account, contact.getJid().toBareJid(), false); + conversation.add(new Message( + conversation, + statusMessage, + Message.ENCRYPTION_NONE, + Message.STATUS_RECEIVED + )); + } } } mXmppConnectionService.updateRosterUi(); -- cgit v1.2.3 From 6b592435cd7bc831f0aac1bb159229dae955fb9b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 3 Dec 2015 18:18:34 +0100 Subject: parse vcard avatars from muc presences --- .../siacs/conversations/parser/MessageParser.java | 2 +- .../siacs/conversations/parser/PresenceParser.java | 117 +++++++++++++++++++-- 2 files changed, 112 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index b4c648fe..3e923af1 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -169,7 +169,7 @@ public class MessageParser extends AbstractParser implements if ("urn:xmpp:avatar:metadata".equals(node)) { Avatar avatar = Avatar.parseMetadata(items); if (avatar != null) { - avatar.owner = from; + avatar.owner = from.toBareJid(); if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { if (account.getJid().toBareJid().equals(from)) { if (account.setAvatar(avatar.getFilename())) { diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 59b94bc0..f9448528 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -1,7 +1,11 @@ package eu.siacs.conversations.parser; +import android.util.Log; + import java.util.ArrayList; +import java.util.List; +import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; @@ -25,19 +29,18 @@ public class PresenceParser extends AbstractParser implements } public void parseConferencePresence(PresencePacket packet, Account account) { - PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine(); final Conversation conversation = packet.getFrom() == null ? null : mXmppConnectionService.find(account, packet.getFrom().toBareJid()); if (conversation != null) { final MucOptions mucOptions = conversation.getMucOptions(); boolean before = mucOptions.online(); - int count = mucOptions.getUsers().size(); - final ArrayList tileUserBefore = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5))); - mucOptions.processPacket(packet, mPgpEngine); - final ArrayList tileUserAfter = new ArrayList<>(mucOptions.getUsers().subList(0,Math.min(mucOptions.getUsers().size(),5))); + int count = mucOptions.getUserCount(); + final List tileUserBefore = mucOptions.getUsers(5); + processConferencePresence(packet, mucOptions); + final List tileUserAfter = mucOptions.getUsers(5); if (!tileUserAfter.equals(tileUserBefore)) { mXmppConnectionService.getAvatarService().clear(conversation); } - if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUsers().size())) { + if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) { mXmppConnectionService.updateConversationUi(); } else if (mucOptions.online()) { mXmppConnectionService.updateMucRosterUi(); @@ -45,6 +48,108 @@ public class PresenceParser extends AbstractParser implements } } + private void processConferencePresence(PresencePacket packet, MucOptions mucOptions) { + final Jid from = packet.getFrom(); + if (!from.isBareJid()) { + final String type = packet.getAttribute("type"); + final Element x = packet.findChild("x", "http://jabber.org/protocol/muc#user"); + Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update")); + final List codes = getStatusCodes(x); + if (type == null) { + if (x != null) { + Element item = x.findChild("item"); + if (item != null && !from.isBareJid()) { + MucOptions.User user = new MucOptions.User(mucOptions,from); + user.setAffiliation(item.getAttribute("affiliation")); + user.setRole(item.getAttribute("role")); + user.setJid(item.getAttributeAsJid("jid")); + if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(mucOptions.getConversation().getJid())) { + mucOptions.setError(MucOptions.ERROR_NO_ERROR); + mucOptions.setSelf(user); + if (mucOptions.mNickChangingInProgress) { + if (mucOptions.onRenameListener != null) { + mucOptions.onRenameListener.onSuccess(); + } + mucOptions.mNickChangingInProgress = false; + } + } else { + mucOptions.addUser(user); + } + if (mXmppConnectionService.getPgpEngine() != null) { + Element signed = packet.findChild("x", "jabber:x:signed"); + if (signed != null) { + Element status = packet.findChild("status"); + String msg = status == null ? "" : status.getContent(); + long keyId = mXmppConnectionService.getPgpEngine().fetchKeyId(mucOptions.getAccount(), msg, signed.getContent()); + if (keyId != 0) { + user.setPgpKeyId(keyId); + } + } + } + if (avatar != null) { + avatar.owner = from; + if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { + user.setAvatar(avatar); + } else { + mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); + } + Log.d(Config.LOGTAG, "user " + avatar.owner + " has avatar"); + } + } + } + } else if (type.equals("unavailable")) { + if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || + packet.getFrom().equals(mucOptions.getConversation().getJid())) { + if (codes.contains(MucOptions.STATUS_CODE_CHANGED_NICK)) { + mucOptions.mNickChangingInProgress = true; + } else if (codes.contains(MucOptions.STATUS_CODE_KICKED)) { + mucOptions.setError(MucOptions.KICKED_FROM_ROOM); + } else if (codes.contains(MucOptions.STATUS_CODE_BANNED)) { + mucOptions.setError(MucOptions.ERROR_BANNED); + } else if (codes.contains(MucOptions.STATUS_CODE_LOST_MEMBERSHIP)) { + mucOptions.setError(MucOptions.ERROR_MEMBERS_ONLY); + } else { + mucOptions.setError(MucOptions.ERROR_UNKNOWN); + } + } else if (!from.isBareJid()){ + mucOptions.deleteUser(from.getResourcepart()); + } + } else if (type.equals("error")) { + Element error = packet.findChild("error"); + if (error != null && error.hasChild("conflict")) { + if (mucOptions.online()) { + if (mucOptions.onRenameListener != null) { + mucOptions.onRenameListener.onFailure(); + } + } else { + mucOptions.setError(MucOptions.ERROR_NICK_IN_USE); + } + } else if (error != null && error.hasChild("not-authorized")) { + mucOptions.setError(MucOptions.ERROR_PASSWORD_REQUIRED); + } else if (error != null && error.hasChild("forbidden")) { + mucOptions.setError(MucOptions.ERROR_BANNED); + } else if (error != null && error.hasChild("registration-required")) { + mucOptions.setError(MucOptions.ERROR_MEMBERS_ONLY); + } + } + } + } + + private static List getStatusCodes(Element x) { + List codes = new ArrayList<>(); + if (x != null) { + for (Element child : x.getChildren()) { + if (child.getName().equals("status")) { + String code = child.getAttribute("code"); + if (code != null) { + codes.add(code); + } + } + } + } + return codes; + } + public void parseContactPresence(final PresencePacket packet, final Account account) { final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator(); final Jid from = packet.getFrom(); -- cgit v1.2.3 From 242887447c09846f8b4eaeb8a29406e5135ec906 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 4 Dec 2015 14:07:16 +0100 Subject: use proposed nick as default nick in mucoptions --- src/main/java/eu/siacs/conversations/parser/PresenceParser.java | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index f9448528..12ffd33f 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -1,11 +1,8 @@ package eu.siacs.conversations.parser; -import android.util.Log; - import java.util.ArrayList; import java.util.List; -import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; @@ -93,7 +90,6 @@ public class PresenceParser extends AbstractParser implements } else { mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); } - Log.d(Config.LOGTAG, "user " + avatar.owner + " has avatar"); } } } -- cgit v1.2.3 From cd9a29718bcf961cdae2bb88ad65066e7347bfb5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 4 Dec 2015 21:36:48 +0100 Subject: properly clear muc user avatar caches --- src/main/java/eu/siacs/conversations/parser/PresenceParser.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 12ffd33f..b8a2a7e9 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -35,7 +35,7 @@ public class PresenceParser extends AbstractParser implements processConferencePresence(packet, mucOptions); final List tileUserAfter = mucOptions.getUsers(5); if (!tileUserAfter.equals(tileUserBefore)) { - mXmppConnectionService.getAvatarService().clear(conversation); + mXmppConnectionService.getAvatarService().clear(mucOptions); } if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) { mXmppConnectionService.updateConversationUi(); @@ -86,7 +86,9 @@ public class PresenceParser extends AbstractParser implements if (avatar != null) { avatar.owner = from; if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) { - user.setAvatar(avatar); + if (user.setAvatar(avatar)) { + mXmppConnectionService.getAvatarService().clear(user); + } } else { mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar); } -- cgit v1.2.3 From 41dcd8005b07cf7a2362dc349ba281defef514dc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 4 Dec 2015 22:03:46 +0100 Subject: parse stanza-id from messages --- .../siacs/conversations/parser/MessageParser.java | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 3e923af1..137cd456 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -163,6 +163,17 @@ public class MessageParser extends AbstractParser implements return null; } + private static String extractStanzaId(Element packet, Jid by) { + for(Element child : packet.getChildren()) { + if (child.getName().equals("stanza-id") + && "urn:xmpp:sid:0".equals(child.getNamespace()) + && by.equals(child.getAttributeAsJid("by"))) { + return child.getAttribute("id"); + } + } + return null; + } + private void parseEvent(final Element event, final Jid from, final Account account) { Element items = event.findChild("items"); String node = items == null ? null : items.getAttribute("node"); @@ -355,6 +366,11 @@ public class MessageParser extends AbstractParser implements } else { message = new Message(conversation, body, Message.ENCRYPTION_NONE, status); } + + if (serverMsgId == null) { + serverMsgId = extractStanzaId(packet, isTypeGroupChat ? conversation.getJid().toBareJid() : account.getServer()); + } + message.setCounterpart(counterpart); message.setRemoteMsgId(remoteMsgId); message.setServerMsgId(serverMsgId); @@ -379,11 +395,11 @@ public class MessageParser extends AbstractParser implements Log.d(Config.LOGTAG,"skipping duplicate message from "+message.getCounterpart().toString()+" "+message.getBody()); return; } + + conversation.add(message); if (query != null) { query.incrementMessageCount(); - } - conversation.add(message); - if (serverMsgId == null) { + } else { if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) { mXmppConnectionService.markRead(conversation); account.activateGracePeriod(); -- cgit v1.2.3 From 6358f641e7acbc5b02a3b7a46289dd4baed63fcf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 5 Dec 2015 18:41:38 +0100 Subject: check for query object as condition to trigger deduplication instead of serverId --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 137cd456..6baefac5 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -388,7 +388,7 @@ public class MessageParser extends AbstractParser implements } } updateLastseen(packet,account,true); - boolean checkForDuplicates = serverMsgId != null + boolean checkForDuplicates = query != null || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")) || message.getType() == Message.TYPE_PRIVATE; if (checkForDuplicates && conversation.hasDuplicateMessage(message)) { -- cgit v1.2.3 From 11e58607c93f152aad82cfe7951355e03274bf47 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 9 Dec 2015 10:30:26 +0100 Subject: when no avatar found show avatar of contact and not the muc user in conferences --- src/main/java/eu/siacs/conversations/parser/PresenceParser.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index b8a2a7e9..d9806dfc 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -110,7 +110,10 @@ public class PresenceParser extends AbstractParser implements mucOptions.setError(MucOptions.ERROR_UNKNOWN); } } else if (!from.isBareJid()){ - mucOptions.deleteUser(from.getResourcepart()); + MucOptions.User user = mucOptions.deleteUser(from.getResourcepart()); + if (user != null) { + mXmppConnectionService.getAvatarService().clear(user); + } } } else if (type.equals("error")) { Element error = packet.findChild("error"); -- cgit v1.2.3 From 5bd70cfee8d3a71cce5bfb0a1a3e3330091333a6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 9 Dec 2015 12:18:06 +0100 Subject: always show conversations with pending subscription requests --- src/main/java/eu/siacs/conversations/parser/PresenceParser.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index d9806dfc..d27182c1 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -200,10 +200,12 @@ public class PresenceParser extends AbstractParser implements mPresenceGenerator.sendPresenceUpdatesTo(contact)); } else { contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST); + final Conversation conversation = mXmppConnectionService.findOrCreateConversation( + account, contact.getJid().toBareJid(), false); final String statusMessage = packet.findChildContent("status"); - if (statusMessage != null && !statusMessage.isEmpty()) { - final Conversation conversation = mXmppConnectionService.findOrCreateConversation( - account, contact.getJid().toBareJid(), false); + if (statusMessage != null + && !statusMessage.isEmpty() + && conversation.countMessages() == 0) { conversation.add(new Message( conversation, statusMessage, -- cgit v1.2.3 From 2262921ff41f3e1b2108c4ab075bfbda27fe090f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 10 Dec 2015 18:28:47 +0100 Subject: properly clean up timed out mam queries --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 6baefac5..2c536f69 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -425,7 +425,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.sendMessagePacket(account, receipt); } } - if (account.getXmppConnection() != null && account.getXmppConnection().getFeatures().advancedStreamFeaturesLoaded()) { + if (account.isOnlineAndConnected() && query == null) { if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { mXmppConnectionService.updateConversation(conversation); } -- cgit v1.2.3 From 55c1129a651b1191273bbf8e49783a4798580375 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 10 Dec 2015 23:05:11 +0100 Subject: notify on mam catchup messages --- .../eu/siacs/conversations/parser/MessageParser.java | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 2c536f69..80886f7f 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -397,15 +397,21 @@ public class MessageParser extends AbstractParser implements } conversation.add(message); - if (query != null) { - query.incrementMessageCount(); - } else { + + if (query == null || query.getWith() == null) { //either no mam or catchup if (status == Message.STATUS_SEND || status == Message.STATUS_SEND_RECEIVED) { mXmppConnectionService.markRead(conversation); - account.activateGracePeriod(); + if (query == null) { + account.activateGracePeriod(); + } } else { message.markUnread(); } + } + + if (query != null) { + query.incrementMessageCount(); + } else { mXmppConnectionService.updateConversationUi(); } @@ -445,7 +451,11 @@ public class MessageParser extends AbstractParser implements if (message.trusted() && message.treatAsDownloadable() != Message.Decision.NEVER && manager.getAutoAcceptFileSize() > 0) { manager.createNewDownloadConnection(message); } else if (!message.isRead()) { - mXmppConnectionService.getNotificationService().push(message); + if (query == null) { + mXmppConnectionService.getNotificationService().push(message); + } else if (query.getWith() == null) { // mam catchup + mXmppConnectionService.getNotificationService().pushFromBacklog(message); + } } } else { //no body if (isTypeGroupChat) { -- cgit v1.2.3 From 293e820a5857ffff5301babc43fc08120a35385c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 11 Dec 2015 13:52:04 +0100 Subject: get rid of lastMessageTransmitted in favor of db query --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 80886f7f..49c3134c 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -329,7 +329,7 @@ public class MessageParser extends AbstractParser implements } if ((body != null || pgpEncrypted != null || axolotlEncrypted != null) && !isMucStatusMessage) { - Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat); + Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, counterpart.toBareJid(), isTypeGroupChat, query); if (isTypeGroupChat) { if (counterpart.getResourcepart().equals(conversation.getMucOptions().getActualNick())) { status = Message.STATUS_SEND_RECEIVED; @@ -431,11 +431,6 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.sendMessagePacket(account, receipt); } } - if (account.isOnlineAndConnected() && query == null) { - if (conversation.setLastMessageTransmitted(System.currentTimeMillis())) { - mXmppConnectionService.updateConversation(conversation); - } - } if (message.getStatus() == Message.STATUS_RECEIVED && conversation.getOtrSession() != null -- cgit v1.2.3 From b2c278c91bc2a733dcb807d7eb7f0d3e7145d9c2 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 11 Dec 2015 19:28:44 +0100 Subject: set bookmark name to room subject if no subject has been set before --- .../java/eu/siacs/conversations/parser/MessageParser.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 49c3134c..d8190b70 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -14,6 +14,7 @@ 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.Bookmark; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; @@ -387,7 +388,7 @@ public class MessageParser extends AbstractParser implements message.setType(Message.TYPE_PRIVATE); } } - updateLastseen(packet,account,true); + updateLastseen(packet, account, true); boolean checkForDuplicates = query != null || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")) || message.getType() == Message.TYPE_PRIVATE; @@ -458,7 +459,14 @@ public class MessageParser extends AbstractParser implements if (packet.hasChild("subject")) { if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) { conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0); - conversation.getMucOptions().setSubject(packet.findChildContent("subject")); + String subject = packet.findChildContent("subject"); + conversation.getMucOptions().setSubject(subject); + final Bookmark bookmark = conversation.getBookmark(); + if (bookmark != null && bookmark.getBookmarkName() == null) { + if (bookmark.setBookmarkName(subject)) { + mXmppConnectionService.pushBookmarks(account); + } + } mXmppConnectionService.updateConversationUi(); return; } -- cgit v1.2.3 From 88523bbb5073867be3faeed27d4b7def1263205b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 12 Dec 2015 15:58:22 +0100 Subject: more detailed logging --- src/main/java/eu/siacs/conversations/parser/IqParser.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index e26a493f..1761e0df 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -117,8 +117,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { Integer id = Integer.valueOf(device.getAttribute("id")); deviceIds.add(id); } catch (NumberFormatException e) { - Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered nvalid node in PEP:" + device.toString() - + ", skipping..."); + Log.e(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+"Encountered invalid node in PEP ("+e.getMessage()+"):" + device.toString()+ ", skipping..."); continue; } } -- cgit v1.2.3 From e10a0b0c4c052adc803a8843a597afe9a13016ac Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 17 Dec 2015 14:30:00 +0100 Subject: let message parser not artifically fail on messages with no to attribute --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index d8190b70..23a23b2c 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -304,17 +304,17 @@ public class MessageParser extends AbstractParser implements final Jid from = packet.getFrom(); final String remoteMsgId = packet.getId(); - if (from == null || to == null) { - Log.d(Config.LOGTAG,"no to or from in: "+packet.toString()); + if (from == null) { + Log.d(Config.LOGTAG,"no from in: "+packet.toString()); return; } boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT; - boolean isProperlyAddressed = !to.isBareJid() || account.countPresences() == 1; + boolean isProperlyAddressed = (to != null ) && (!to.isBareJid() || account.countPresences() == 1); boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status"); if (packet.fromAccount(account)) { status = Message.STATUS_SEND; - counterpart = to; + counterpart = to != null ? to : account.getJid(); } else { status = Message.STATUS_RECEIVED; counterpart = from; -- cgit v1.2.3 From 73e2389eeec92f57da2b50ce4a40395e4cbe0803 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 31 Dec 2015 18:06:11 +0100 Subject: use actual message timestamp instead of delay when updating last seen. fixes #1618 --- src/main/java/eu/siacs/conversations/parser/AbstractParser.java | 8 ++++---- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java index 18331796..7d399073 100644 --- a/src/main/java/eu/siacs/conversations/parser/AbstractParser.java +++ b/src/main/java/eu/siacs/conversations/parser/AbstractParser.java @@ -11,6 +11,7 @@ import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xmpp.jid.Jid; +import eu.siacs.conversations.xmpp.stanzas.AbstractStanza; public abstract class AbstractParser { @@ -47,14 +48,13 @@ public abstract class AbstractParser { return dateFormat.parse(timestamp); } - protected void updateLastseen(final Element packet, final Account account, final boolean presenceOverwrite) { - updateLastseen(packet, account, packet.getAttributeAsJid("from"), presenceOverwrite); + protected void updateLastseen(final AbstractStanza packet, final Account account, final boolean presenceOverwrite) { + updateLastseen(getTimestamp(packet), account, packet.getFrom(), presenceOverwrite); } - protected void updateLastseen(final Element packet, final Account account, final Jid from, final boolean presenceOverwrite) { + protected void updateLastseen(long timestamp, final Account account, final Jid from, final boolean presenceOverwrite) { final String presence = from == null || from.isBareJid() ? "" : from.getResourcepart(); final Contact contact = account.getRoster().getContact(from); - final long timestamp = getTimestamp(packet); if (timestamp >= contact.lastseen.time) { contact.lastseen.time = timestamp; if (!presence.isEmpty() && presenceOverwrite) { diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 23a23b2c..345e8395 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -382,13 +382,14 @@ public class MessageParser extends AbstractParser implements Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart()); message.setTrueCounterpart(trueCounterpart); if (trueCounterpart != null) { - updateLastseen(packet,account,trueCounterpart,false); + updateLastseen(timestamp, account, trueCounterpart, false); } if (!isTypeGroupChat) { message.setType(Message.TYPE_PRIVATE); } + } else { + updateLastseen(timestamp, account, packet.getFrom(), true); } - updateLastseen(packet, account, true); boolean checkForDuplicates = query != null || (isTypeGroupChat && packet.hasChild("delay","urn:xmpp:delay")) || message.getType() == Message.TYPE_PRIVATE; @@ -498,7 +499,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.markRead(conversation); } } else { - updateLastseen(packet, account, true); + updateLastseen(timestamp, account, packet.getFrom(), true); final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED); Message message = displayedMessage == null ? null : displayedMessage.prev(); while (message != null -- cgit v1.2.3 From 2eef37174e1034995d79af03cd1c0a3f8f9f3488 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 31 Jan 2016 14:42:35 +0100 Subject: fixed false set of subject in conference with empty body tag --- src/main/java/eu/siacs/conversations/parser/MessageParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 345e8395..d8eae969 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -454,7 +454,7 @@ public class MessageParser extends AbstractParser implements mXmppConnectionService.getNotificationService().pushFromBacklog(message); } } - } else { //no body + } else if (!packet.hasChild("body")){ //no body if (isTypeGroupChat) { Conversation conversation = mXmppConnectionService.find(account, from.toBareJid()); if (packet.hasChild("subject")) { -- cgit v1.2.3 From a3e11415ec06945bea88b49c99a5662773c8bf17 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 1 Feb 2016 12:11:40 +0100 Subject: refactored user handling in conferences. show try again button when conference has errors --- src/main/java/eu/siacs/conversations/parser/PresenceParser.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/parser') diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index d27182c1..a07b42a9 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -1,8 +1,12 @@ package eu.siacs.conversations.parser; +import android.util.Log; + import java.util.ArrayList; import java.util.List; + +import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.PgpEngine; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; @@ -35,6 +39,7 @@ public class PresenceParser extends AbstractParser implements processConferencePresence(packet, mucOptions); final List tileUserAfter = mucOptions.getUsers(5); if (!tileUserAfter.equals(tileUserBefore)) { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": update tiles for "+conversation.getName()); mXmppConnectionService.getAvatarService().clear(mucOptions); } if (before != mucOptions.online() || (mucOptions.online() && count != mucOptions.getUserCount())) { @@ -56,12 +61,13 @@ public class PresenceParser extends AbstractParser implements if (x != null) { Element item = x.findChild("item"); if (item != null && !from.isBareJid()) { + mucOptions.setError(MucOptions.ERROR_NO_ERROR); MucOptions.User user = new MucOptions.User(mucOptions,from); user.setAffiliation(item.getAttribute("affiliation")); user.setRole(item.getAttribute("role")); user.setJid(item.getAttributeAsJid("jid")); if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || packet.getFrom().equals(mucOptions.getConversation().getJid())) { - mucOptions.setError(MucOptions.ERROR_NO_ERROR); + mucOptions.setOnline(); mucOptions.setSelf(user); if (mucOptions.mNickChangingInProgress) { if (mucOptions.onRenameListener != null) { @@ -108,6 +114,7 @@ public class PresenceParser extends AbstractParser implements mucOptions.setError(MucOptions.ERROR_MEMBERS_ONLY); } else { mucOptions.setError(MucOptions.ERROR_UNKNOWN); + Log.d(Config.LOGTAG, "unknown error in conference: " + packet); } } else if (!from.isBareJid()){ MucOptions.User user = mucOptions.deleteUser(from.getResourcepart()); -- cgit v1.2.3