From 27690865a63e1c1f349f876619df78c867c8f9af Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 13 Jul 2016 18:10:10 +0200 Subject: [PATCH] respond to XEP-0202: Entity Time --- .../generator/AbstractGenerator.java | 6 ++++++ .../conversations/generator/IqGenerator.java | 14 ++++++++++++++ .../eu/siacs/conversations/parser/IqParser.java | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 43ffe7241..cdc3840f1 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -42,6 +42,9 @@ public abstract class AbstractGenerator { private final String[] MESSAGE_CORRECTION_FEATURES = { "urn:xmpp:message-correct:0" }; + private final String[] PRIVACY_SENSITIVE = { + "urn:xmpp:time" //XEP-0202: Entity Time leaks time zone + }; private String mVersion = null; protected final String IDENTITY_NAME = "Conversations"; protected final String IDENTITY_TYPE = "phone"; @@ -99,6 +102,9 @@ public abstract class AbstractGenerator { if (Config.supportOmemo()) { features.add(AxolotlService.PEP_DEVICE_LIST_NOTIFY); } + if (!mXmppConnectionService.useTorToConnect()) { + features.addAll(Arrays.asList(PRIVACY_SENSITIVE)); + } Collections.sort(features); return features; } diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 2e441727c..ca4763494 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -15,6 +15,7 @@ import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.TimeZone; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.AxolotlService; @@ -61,6 +62,19 @@ public class IqGenerator extends AbstractGenerator { return packet; } + public IqPacket entityTimeResponse(IqPacket request) { + final IqPacket packet = request.generateResponse(IqPacket.TYPE.RESULT); + Element time = packet.addChild("time","urn:xmpp:time"); + final long now = System.currentTimeMillis(); + time.addChild("utc").setContent(getTimestamp(now)); + TimeZone ourTimezone = TimeZone.getDefault(); + long offsetSeconds = ourTimezone.getOffset(now) / 1000; + long offsetMinutes = offsetSeconds % (60 * 60); + long offsetHours = offsetSeconds / (60 * 60); + time.addChild("tzo").setContent(String.format("%02d",offsetHours)+":"+String.format("%02d",offsetMinutes)); + return packet; + } + protected IqPacket publish(final String node, final Element item) { final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); final Element pubsub = packet.addChild("pubsub", diff --git a/src/main/java/eu/siacs/conversations/parser/IqParser.java b/src/main/java/eu/siacs/conversations/parser/IqParser.java index f5f609db2..4e925e97d 100644 --- a/src/main/java/eu/siacs/conversations/parser/IqParser.java +++ b/src/main/java/eu/siacs/conversations/parser/IqParser.java @@ -277,6 +277,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { @Override public void onIqPacketReceived(final Account account, final IqPacket packet) { + final boolean isGet = packet.getType() == IqPacket.TYPE.GET; if (packet.getType() == IqPacket.TYPE.ERROR || packet.getType() == IqPacket.TYPE.TIMEOUT) { return; } else if (packet.hasChild("query", Xmlns.ROSTER) && packet.fromServer(account)) { @@ -348,12 +349,23 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived { } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) { final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(packet); mXmppConnectionService.sendIqPacket(account, response, null); - } else if (packet.hasChild("query","jabber:iq:version")) { + } else if (packet.hasChild("query","jabber:iq:version") && isGet) { final IqPacket response = mXmppConnectionService.getIqGenerator().versionResponse(packet); mXmppConnectionService.sendIqPacket(account,response,null); - } else if (packet.hasChild("ping", "urn:xmpp:ping")) { + } else if (packet.hasChild("ping", "urn:xmpp:ping") && isGet) { final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT); mXmppConnectionService.sendIqPacket(account, response, null); + } else if (packet.hasChild("time","urn:xmpp:time") && isGet) { + final IqPacket response; + if (mXmppConnectionService.useTorToConnect()) { + response = packet.generateResponse(IqPacket.TYPE.ERROR); + final Element error = response.addChild("error"); + error.setAttribute("type","cancel"); + error.addChild("not-allowed","urn:ietf:params:xml:ns:xmpp-stanzas"); + } else { + response = mXmppConnectionService.getIqGenerator().entityTimeResponse(packet); + } + mXmppConnectionService.sendIqPacket(account,response, null); } else { if (packet.getType() == IqPacket.TYPE.GET || packet.getType() == IqPacket.TYPE.SET) { final IqPacket response = packet.generateResponse(IqPacket.TYPE.ERROR);