Search in sources :

Example 76 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class AxolotlService method completeSession.

private void completeSession(XmppAxolotlSession session) {
    final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().asBareJid(), getOwnDeviceId());
    axolotlMessage.addDevice(session, true);
    try {
        final Jid jid = Jid.of(session.getRemoteAddress().getName());
        MessagePacket packet = mXmppConnectionService.getMessageGenerator().generateKeyTransportMessage(jid, axolotlMessage);
        mXmppConnectionService.sendMessagePacket(account, packet);
    } catch (IllegalArgumentException e) {
        throw new Error("Remote addresses are created from jid and should convert back to jid", e);
    }
}
Also used : MessagePacket(eu.siacs.conversations.xmpp.stanzas.MessagePacket) Jid(eu.siacs.conversations.xmpp.Jid)

Example 77 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class IqParser method 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;
    }
    if (packet.hasChild("query", Namespace.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) {
            account.getRoster().markAllAsNotInRoster();
        }
        this.rosterItems(account, query);
    } else if ((packet.hasChild("block", Namespace.BLOCKING) || packet.hasChild("blocklist", Namespace.BLOCKING)) && packet.fromServer(account)) {
        // Block list or block push.
        Log.d(Config.LOGTAG, "Received blocklist update from server");
        final Element blocklist = packet.findChild("blocklist", Namespace.BLOCKING);
        final Element block = packet.findChild("block", Namespace.BLOCKING);
        final Collection<Element> items = blocklist != null ? blocklist.getChildren() : (block != null ? block.getChildren() : null);
        // Otherwise, just update the existing blocklist.
        if (packet.getType() == IqPacket.TYPE.RESULT) {
            account.clearBlocklist();
            account.getXmppConnection().getFeatures().setBlockListRequested(true);
        }
        if (items != null) {
            final Collection<Jid> jids = new ArrayList<>(items.size());
            // Create a collection of Jids from the packet
            for (final Element item : items) {
                if (item.getName().equals("item")) {
                    final Jid jid = InvalidJid.getNullForInvalid(item.getAttributeAsJid("jid"));
                    if (jid != null) {
                        jids.add(jid);
                    }
                }
            }
            account.getBlocklist().addAll(jids);
            if (packet.getType() == IqPacket.TYPE.SET) {
                boolean removed = false;
                for (Jid jid : jids) {
                    removed |= mXmppConnectionService.removeBlockedConversations(account, jid);
                }
                if (removed) {
                    mXmppConnectionService.updateConversationUi();
                }
            }
        }
        // Update the UI
        mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.BLOCKED);
        if (packet.getType() == IqPacket.TYPE.SET) {
            final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
            mXmppConnectionService.sendIqPacket(account, response, null);
        }
    } else if (packet.hasChild("unblock", Namespace.BLOCKING) && packet.fromServer(account) && packet.getType() == IqPacket.TYPE.SET) {
        Log.d(Config.LOGTAG, "Received unblock update from server");
        final Collection<Element> items = packet.findChild("unblock", Namespace.BLOCKING).getChildren();
        if (items.size() == 0) {
            // No children to unblock == unblock all
            account.getBlocklist().clear();
        } else {
            final Collection<Jid> jids = new ArrayList<>(items.size());
            for (final Element item : items) {
                if (item.getName().equals("item")) {
                    final Jid jid = InvalidJid.getNullForInvalid(item.getAttributeAsJid("jid"));
                    if (jid != null) {
                        jids.add(jid);
                    }
                }
            }
            account.getBlocklist().removeAll(jids);
        }
        mXmppConnectionService.updateBlocklistUi(OnUpdateBlocklist.Status.UNBLOCKED);
        final IqPacket response = packet.generateResponse(IqPacket.TYPE.RESULT);
        mXmppConnectionService.sendIqPacket(account, response, null);
    } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb") || packet.hasChild("data", "http://jabber.org/protocol/ibb") || packet.hasChild("close", "http://jabber.org/protocol/ibb")) {
        mXmppConnectionService.getJingleConnectionManager().deliverIbbPacket(account, packet);
    } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
        final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(account, packet);
        mXmppConnectionService.sendIqPacket(account, response, null);
    } 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") && 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() || account.isOnion()) {
            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);
            final Element error = response.addChild("error");
            error.setAttribute("type", "cancel");
            error.addChild("feature-not-implemented", "urn:ietf:params:xml:ns:xmpp-stanzas");
            account.getXmppConnection().sendIqPacket(response, null);
        }
    }
}
Also used : InvalidJid(eu.siacs.conversations.xmpp.InvalidJid) Jid(eu.siacs.conversations.xmpp.Jid) Element(eu.siacs.conversations.xml.Element) ArrayList(java.util.ArrayList) Collection(java.util.Collection) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket)

Example 78 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class PresenceParser method parseContactPresence.

private void parseContactPresence(final PresencePacket packet, final Account account) {
    final PresenceGenerator mPresenceGenerator = mXmppConnectionService.getPresenceGenerator();
    final Jid from = packet.getFrom();
    if (from == null || from.equals(account.getJid())) {
        return;
    }
    final String type = packet.getAttribute("type");
    final Contact contact = account.getRoster().getContact(from);
    if (type == null) {
        final String resource = from.isBareJid() ? "" : from.getResource();
        Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
        if (avatar != null && (!contact.isSelf() || account.getAvatar() == null)) {
            avatar.owner = from.asBareJid();
            if (mXmppConnectionService.getFileBackend().isAvatarCached(avatar)) {
                if (avatar.owner.equals(account.getJid().asBareJid())) {
                    account.setAvatar(avatar.getFilename());
                    mXmppConnectionService.databaseBackend.updateAccount(account);
                    mXmppConnectionService.getAvatarService().clear(account);
                    mXmppConnectionService.updateConversationUi();
                    mXmppConnectionService.updateAccountUi();
                } else {
                    contact.setAvatar(avatar);
                    mXmppConnectionService.syncRoster(account);
                    mXmppConnectionService.getAvatarService().clear(contact);
                    mXmppConnectionService.updateConversationUi();
                    mXmppConnectionService.updateRosterUi();
                }
            } else if (mXmppConnectionService.isDataSaverDisabled()) {
                mXmppConnectionService.fetchAvatar(account, avatar);
            }
        }
        if (mXmppConnectionService.isMuc(account, from)) {
            return;
        }
        int sizeBefore = contact.getPresences().size();
        final String show = packet.findChildContent("show");
        final Element caps = packet.findChild("c", "http://jabber.org/protocol/caps");
        final String message = packet.findChildContent("status");
        final Presence presence = Presence.parse(show, caps, message);
        contact.updatePresence(resource, presence);
        if (presence.hasCaps()) {
            mXmppConnectionService.fetchCaps(account, from, presence);
        }
        final Element idle = packet.findChild("idle", Namespace.IDLE);
        if (idle != null) {
            try {
                final String since = idle.getAttribute("since");
                contact.setLastseen(AbstractParser.parseTimestamp(since));
                contact.flagInactive();
            } catch (Throwable throwable) {
                if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) {
                    contact.flagActive();
                }
            }
        } else {
            if (contact.setLastseen(AbstractParser.parseTimestamp(packet))) {
                contact.flagActive();
            }
        }
        PgpEngine pgp = mXmppConnectionService.getPgpEngine();
        Element x = packet.findChild("x", "jabber:x:signed");
        if (pgp != null && x != null) {
            final String status = packet.findChildContent("status");
            final long keyId = pgp.fetchKeyId(account, status, x.getContent());
            if (keyId != 0 && contact.setPgpKeyId(keyId)) {
                Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": found OpenPGP key id for " + contact.getJid() + " " + OpenPgpUtils.convertKeyIdToHex(keyId));
                mXmppConnectionService.syncRoster(account);
            }
        }
        boolean online = sizeBefore < contact.getPresences().size();
        mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, online);
    } else if (type.equals("unavailable")) {
        if (contact.setLastseen(AbstractParser.parseTimestamp(packet, 0L, true))) {
            contact.flagInactive();
        }
        if (from.isBareJid()) {
            contact.clearPresences();
        } else {
            contact.removePresence(from.getResource());
        }
        if (contact.getShownStatus() == Presence.Status.OFFLINE) {
            contact.flagInactive();
        }
        mXmppConnectionService.onContactStatusChanged.onContactStatusChanged(contact, false);
    } else if (type.equals("subscribe")) {
        if (contact.setPresenceName(packet.findChildContent("nick", Namespace.NICK))) {
            mXmppConnectionService.syncRoster(account);
            mXmppConnectionService.getAvatarService().clear(contact);
        }
        if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
            mXmppConnectionService.sendPresencePacket(account, mPresenceGenerator.sendPresenceUpdatesTo(contact));
        } else {
            contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
            final Conversation conversation = mXmppConnectionService.findOrCreateConversation(account, contact.getJid().asBareJid(), false, false);
            final String statusMessage = packet.findChildContent("status");
            if (statusMessage != null && !statusMessage.isEmpty() && conversation.countMessages() == 0) {
                conversation.add(new Message(conversation, statusMessage, Message.ENCRYPTION_NONE, Message.STATUS_RECEIVED));
            }
        }
    }
    mXmppConnectionService.updateRosterUi();
}
Also used : PresenceGenerator(eu.siacs.conversations.generator.PresenceGenerator) InvalidJid(eu.siacs.conversations.xmpp.InvalidJid) Jid(eu.siacs.conversations.xmpp.Jid) Message(eu.siacs.conversations.entities.Message) Element(eu.siacs.conversations.xml.Element) PgpEngine(eu.siacs.conversations.crypto.PgpEngine) Conversation(eu.siacs.conversations.entities.Conversation) Avatar(eu.siacs.conversations.xmpp.pep.Avatar) Contact(eu.siacs.conversations.entities.Contact) Presence(eu.siacs.conversations.entities.Presence)

Example 79 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class PresenceParser method processConferencePresence.

private void processConferencePresence(PresencePacket packet, Conversation conversation) {
    MucOptions mucOptions = conversation.getMucOptions();
    final Jid jid = conversation.getAccount().getJid();
    final Jid from = packet.getFrom();
    if (!from.isBareJid()) {
        final String type = packet.getAttribute("type");
        final Element x = packet.findChild("x", Namespace.MUC_USER);
        Avatar avatar = Avatar.parsePresence(packet.findChild("x", "vcard-temp:x:update"));
        final List<String> codes = getStatusCodes(x);
        if (type == null) {
            if (x != null) {
                Element item = x.findChild("item");
                if (item != null && !from.isBareJid()) {
                    mucOptions.setError(MucOptions.Error.NONE);
                    MucOptions.User user = parseItem(conversation, item, from);
                    if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE) || (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && jid.equals(InvalidJid.getNullForInvalid(item.getAttributeAsJid("jid"))))) {
                        if (mucOptions.setOnline()) {
                            mXmppConnectionService.getAvatarService().clear(mucOptions);
                        }
                        if (mucOptions.setSelf(user)) {
                            Log.d(Config.LOGTAG, "role or affiliation changed");
                            mXmppConnectionService.databaseBackend.updateConversation(conversation);
                        }
                        mXmppConnectionService.persistSelfNick(user);
                        invokeRenameListener(mucOptions, true);
                    }
                    boolean isNew = mucOptions.updateUser(user);
                    final AxolotlService axolotlService = conversation.getAccount().getAxolotlService();
                    Contact contact = user.getContact();
                    if (isNew && user.getRealJid() != null && mucOptions.isPrivateAndNonAnonymous() && (contact == null || !contact.mutualPresenceSubscription()) && axolotlService.hasEmptyDeviceList(user.getRealJid())) {
                        axolotlService.fetchDeviceIds(user.getRealJid());
                    }
                    if (codes.contains(MucOptions.STATUS_CODE_ROOM_CREATED) && mucOptions.autoPushConfiguration()) {
                        Log.d(Config.LOGTAG, mucOptions.getAccount().getJid().asBareJid() + ": room '" + mucOptions.getConversation().getJid().asBareJid() + "' created. pushing default configuration");
                        mXmppConnectionService.pushConferenceConfiguration(mucOptions.getConversation(), IqGenerator.defaultChannelConfiguration(), null);
                    }
                    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)) {
                            if (user.setAvatar(avatar)) {
                                mXmppConnectionService.getAvatarService().clear(user);
                            }
                            if (user.getRealJid() != null) {
                                final Contact c = conversation.getAccount().getRoster().getContact(user.getRealJid());
                                c.setAvatar(avatar);
                                mXmppConnectionService.syncRoster(conversation.getAccount());
                                mXmppConnectionService.getAvatarService().clear(c);
                                mXmppConnectionService.updateRosterUi();
                            }
                        } else if (mXmppConnectionService.isDataSaverDisabled()) {
                            mXmppConnectionService.fetchAvatar(mucOptions.getAccount(), avatar);
                        }
                    }
                }
            }
        } else if (type.equals("unavailable")) {
            final boolean fullJidMatches = from.equals(mucOptions.getSelf().getFullJid());
            if (x.hasChild("destroy") && fullJidMatches) {
                Element destroy = x.findChild("destroy");
                final Jid alternate = destroy == null ? null : InvalidJid.getNullForInvalid(destroy.getAttributeAsJid("jid"));
                mucOptions.setError(MucOptions.Error.DESTROYED);
                if (alternate != null) {
                    Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": muc destroyed. alternate location " + alternate);
                }
            } else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN) && fullJidMatches) {
                mucOptions.setError(MucOptions.Error.SHUTDOWN);
            } else if (codes.contains(MucOptions.STATUS_CODE_SELF_PRESENCE)) {
                if (codes.contains(MucOptions.STATUS_CODE_KICKED)) {
                    mucOptions.setError(MucOptions.Error.KICKED);
                } 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 if (codes.contains(MucOptions.STATUS_CODE_AFFILIATION_CHANGE)) {
                    mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
                } else if (codes.contains(MucOptions.STATUS_CODE_SHUTDOWN)) {
                    mucOptions.setError(MucOptions.Error.SHUTDOWN);
                } else if (!codes.contains(MucOptions.STATUS_CODE_CHANGED_NICK)) {
                    mucOptions.setError(MucOptions.Error.UNKNOWN);
                    Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
                }
            } else if (!from.isBareJid()) {
                Element item = x.findChild("item");
                if (item != null) {
                    mucOptions.updateUser(parseItem(conversation, item, from));
                }
                MucOptions.User user = mucOptions.deleteUser(from);
                if (user != null) {
                    mXmppConnectionService.getAvatarService().clear(user);
                }
            }
        } else if (type.equals("error")) {
            final Element error = packet.findChild("error");
            if (error == null) {
                return;
            }
            if (error.hasChild("conflict")) {
                if (mucOptions.online()) {
                    invokeRenameListener(mucOptions, false);
                } else {
                    mucOptions.setError(MucOptions.Error.NICK_IN_USE);
                }
            } else if (error.hasChild("not-authorized")) {
                mucOptions.setError(MucOptions.Error.PASSWORD_REQUIRED);
            } else if (error.hasChild("forbidden")) {
                mucOptions.setError(MucOptions.Error.BANNED);
            } else if (error.hasChild("registration-required")) {
                mucOptions.setError(MucOptions.Error.MEMBERS_ONLY);
            } else if (error.hasChild("resource-constraint")) {
                mucOptions.setError(MucOptions.Error.RESOURCE_CONSTRAINT);
            } else if (error.hasChild("remote-server-timeout")) {
                mucOptions.setError(MucOptions.Error.REMOTE_SERVER_TIMEOUT);
            } else if (error.hasChild("gone")) {
                final String gone = error.findChildContent("gone");
                final Jid alternate;
                if (gone != null) {
                    final XmppUri xmppUri = new XmppUri(gone);
                    if (xmppUri.isValidJid()) {
                        alternate = xmppUri.getJid();
                    } else {
                        alternate = null;
                    }
                } else {
                    alternate = null;
                }
                mucOptions.setError(MucOptions.Error.DESTROYED);
                if (alternate != null) {
                    Log.d(Config.LOGTAG, conversation.getAccount().getJid().asBareJid() + ": muc destroyed. alternate location " + alternate);
                }
            } else {
                final String text = error.findChildContent("text");
                if (text != null && text.contains("attribute 'to'")) {
                    if (mucOptions.online()) {
                        invokeRenameListener(mucOptions, false);
                    } else {
                        mucOptions.setError(MucOptions.Error.INVALID_NICK);
                    }
                } else {
                    mucOptions.setError(MucOptions.Error.UNKNOWN);
                    Log.d(Config.LOGTAG, "unknown error in conference: " + packet);
                }
            }
        }
    }
}
Also used : AxolotlService(eu.siacs.conversations.crypto.axolotl.AxolotlService) MucOptions(eu.siacs.conversations.entities.MucOptions) InvalidJid(eu.siacs.conversations.xmpp.InvalidJid) Jid(eu.siacs.conversations.xmpp.Jid) XmppUri(eu.siacs.conversations.utils.XmppUri) Element(eu.siacs.conversations.xml.Element) Avatar(eu.siacs.conversations.xmpp.pep.Avatar) Contact(eu.siacs.conversations.entities.Contact)

Example 80 with Jid

use of eu.siacs.conversations.xmpp.Jid in project Conversations by siacs.

the class AbstractParser method parseTimestamp.

public static Long parseTimestamp(Element element, Long d, boolean ignoreCsiAndSm) {
    long min = Long.MAX_VALUE;
    boolean returnDefault = true;
    final Jid to;
    if (ignoreCsiAndSm && element instanceof AbstractStanza) {
        to = ((AbstractStanza) element).getTo();
    } else {
        to = null;
    }
    for (Element child : element.getChildren()) {
        if ("delay".equals(child.getName()) && "urn:xmpp:delay".equals(child.getNamespace())) {
            final Jid f = to == null ? null : InvalidJid.getNullForInvalid(child.getAttributeAsJid("from"));
            if (f != null && (to.asBareJid().equals(f) || to.getDomain().equals(f))) {
                continue;
            }
            final String stamp = child.getAttribute("stamp");
            if (stamp != null) {
                try {
                    min = Math.min(min, AbstractParser.parseTimestamp(stamp));
                    returnDefault = false;
                } catch (Throwable t) {
                // ignore
                }
            }
        }
    }
    if (returnDefault) {
        return d;
    } else {
        return min;
    }
}
Also used : InvalidJid(eu.siacs.conversations.xmpp.InvalidJid) Jid(eu.siacs.conversations.xmpp.Jid) AbstractStanza(eu.siacs.conversations.xmpp.stanzas.AbstractStanza) Element(eu.siacs.conversations.xml.Element)

Aggregations

Jid (eu.siacs.conversations.xmpp.Jid)106 Account (eu.siacs.conversations.entities.Account)35 Element (eu.siacs.conversations.xml.Element)24 Conversation (eu.siacs.conversations.entities.Conversation)22 Contact (eu.siacs.conversations.entities.Contact)17 InvalidJid (eu.siacs.conversations.xmpp.InvalidJid)16 IqPacket (eu.siacs.conversations.xmpp.stanzas.IqPacket)16 Intent (android.content.Intent)15 ArrayList (java.util.ArrayList)13 MucOptions (eu.siacs.conversations.entities.MucOptions)12 Bookmark (eu.siacs.conversations.entities.Bookmark)10 AxolotlService (eu.siacs.conversations.crypto.axolotl.AxolotlService)7 Message (eu.siacs.conversations.entities.Message)7 OnIqPacketReceived (eu.siacs.conversations.xmpp.OnIqPacketReceived)6 MessagePacket (eu.siacs.conversations.xmpp.stanzas.MessagePacket)6 Map (java.util.Map)6 XmppUri (eu.siacs.conversations.utils.XmppUri)5 XmppConnectionService (eu.siacs.conversations.services.XmppConnectionService)4 Avatar (eu.siacs.conversations.xmpp.pep.Avatar)4 HashMap (java.util.HashMap)4