Search in sources :

Example 1 with InvalidJidException

use of eu.siacs.conversations.xmpp.jid.InvalidJidException in project Conversations by siacs.

the class XmppConnectionService method sendMessage.

private void sendMessage(final Message message, final boolean resend, final boolean delay) {
    final Account account = message.getConversation().getAccount();
    if (account.setShowErrorNotification(true)) {
        databaseBackend.updateAccount(account);
        mNotificationService.updateErrorNotification();
    }
    final Conversation conversation = message.getConversation();
    account.deactivateGracePeriod();
    MessagePacket packet = null;
    final boolean addToConversation = (conversation.getMode() != Conversation.MODE_MULTI || !Patches.BAD_MUC_REFLECTION.contains(account.getServerIdentity())) && !message.edited();
    boolean saveInDb = addToConversation;
    message.setStatus(Message.STATUS_WAITING);
    if (!resend && message.getEncryption() != Message.ENCRYPTION_OTR) {
        message.getConversation().endOtrIfNeeded();
        message.getConversation().findUnsentMessagesWithEncryption(Message.ENCRYPTION_OTR, new Conversation.OnMessageFound() {

            @Override
            public void onMessageFound(Message message) {
                markMessage(message, Message.STATUS_SEND_FAILED);
            }
        });
    }
    if (account.isOnlineAndConnected()) {
        switch(message.getEncryption()) {
            case Message.ENCRYPTION_NONE:
                if (message.needsUploading()) {
                    if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize()) || message.fixCounterpart()) {
                        this.sendFileMessage(message, delay);
                    } else {
                        break;
                    }
                } else {
                    packet = mMessageGenerator.generateChat(message);
                }
                break;
            case Message.ENCRYPTION_PGP:
            case Message.ENCRYPTION_DECRYPTED:
                if (message.needsUploading()) {
                    if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize()) || message.fixCounterpart()) {
                        this.sendFileMessage(message, delay);
                    } else {
                        break;
                    }
                } else {
                    packet = mMessageGenerator.generatePgpChat(message);
                }
                break;
            case Message.ENCRYPTION_OTR:
                SessionImpl otrSession = conversation.getOtrSession();
                if (otrSession != null && otrSession.getSessionStatus() == SessionStatus.ENCRYPTED) {
                    try {
                        message.setCounterpart(Jid.fromSessionID(otrSession.getSessionID()));
                    } catch (InvalidJidException e) {
                        break;
                    }
                    if (message.needsUploading()) {
                        mJingleConnectionManager.createNewConnection(message);
                    } else {
                        packet = mMessageGenerator.generateOtrChat(message);
                    }
                } else if (otrSession == null) {
                    if (message.fixCounterpart()) {
                        conversation.startOtrSession(message.getCounterpart().getResourcepart(), true);
                    } else {
                        Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not fix counterpart for OTR message to contact " + message.getContact().getJid());
                        break;
                    }
                } else {
                    Log.d(Config.LOGTAG, account.getJid().toBareJid() + " OTR session with " + message.getContact() + " is in wrong state: " + otrSession.getSessionStatus().toString());
                }
                break;
            case Message.ENCRYPTION_AXOLOTL:
                message.setFingerprint(account.getAxolotlService().getOwnFingerprint());
                if (message.needsUploading()) {
                    if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize()) || message.fixCounterpart()) {
                        this.sendFileMessage(message, delay);
                    } else {
                        break;
                    }
                } else {
                    XmppAxolotlMessage axolotlMessage = account.getAxolotlService().fetchAxolotlMessageFromCache(message);
                    if (axolotlMessage == null) {
                        account.getAxolotlService().preparePayloadMessage(message, delay);
                    } else {
                        packet = mMessageGenerator.generateAxolotlChat(message, axolotlMessage);
                    }
                }
                break;
        }
        if (packet != null) {
            if (account.getXmppConnection().getFeatures().sm() || (conversation.getMode() == Conversation.MODE_MULTI && message.getCounterpart().isBareJid())) {
                message.setStatus(Message.STATUS_UNSEND);
            } else {
                message.setStatus(Message.STATUS_SEND);
            }
        }
    } else {
        switch(message.getEncryption()) {
            case Message.ENCRYPTION_DECRYPTED:
                if (!message.needsUploading()) {
                    String pgpBody = message.getEncryptedBody();
                    String decryptedBody = message.getBody();
                    message.setBody(pgpBody);
                    message.setEncryption(Message.ENCRYPTION_PGP);
                    if (message.edited()) {
                        message.setBody(decryptedBody);
                        message.setEncryption(Message.ENCRYPTION_DECRYPTED);
                        databaseBackend.updateMessage(message, message.getEditedId());
                        updateConversationUi();
                        return;
                    } else {
                        databaseBackend.createMessage(message);
                        saveInDb = false;
                        message.setBody(decryptedBody);
                        message.setEncryption(Message.ENCRYPTION_DECRYPTED);
                    }
                }
                break;
            case Message.ENCRYPTION_OTR:
                if (!conversation.hasValidOtrSession() && message.getCounterpart() != null) {
                    Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": create otr session without starting for " + message.getContact().getJid());
                    conversation.startOtrSession(message.getCounterpart().getResourcepart(), false);
                }
                break;
            case Message.ENCRYPTION_AXOLOTL:
                message.setFingerprint(account.getAxolotlService().getOwnFingerprint());
                break;
        }
    }
    if (resend) {
        if (packet != null && addToConversation) {
            if (account.getXmppConnection().getFeatures().sm() || (conversation.getMode() == Conversation.MODE_MULTI && message.getCounterpart().isBareJid())) {
                markMessage(message, Message.STATUS_UNSEND);
            } else {
                markMessage(message, Message.STATUS_SEND);
            }
        }
    } else {
        if (addToConversation) {
            conversation.add(message);
        }
        if (saveInDb) {
            databaseBackend.createMessage(message);
        } else if (message.edited()) {
            databaseBackend.updateMessage(message, message.getEditedId());
        }
        updateConversationUi();
    }
    if (packet != null) {
        if (delay) {
            mMessageGenerator.addDelay(packet, message.getTimeSent());
        }
        if (conversation.setOutgoingChatState(Config.DEFAULT_CHATSTATE)) {
            if (this.sendChatStates()) {
                packet.addChild(ChatState.toElement(conversation.getOutgoingChatState()));
            }
        }
        sendMessagePacket(account, packet);
    }
}
Also used : MessagePacket(eu.siacs.conversations.xmpp.stanzas.MessagePacket) Account(eu.siacs.conversations.entities.Account) XmppAxolotlMessage(eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage) Message(eu.siacs.conversations.entities.Message) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException) Conversation(eu.siacs.conversations.entities.Conversation) XmppAxolotlMessage(eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage) SessionImpl(net.java.otr4j.session.SessionImpl)

Example 2 with InvalidJidException

use of eu.siacs.conversations.xmpp.jid.InvalidJidException in project Conversations by siacs.

the class VerifyOTRActivity method handleIntent.

protected boolean handleIntent(Intent intent) {
    if (intent != null && intent.getAction().equals(ACTION_VERIFY_CONTACT)) {
        this.mAccount = extractAccount(intent);
        if (this.mAccount == null) {
            return false;
        }
        try {
            this.mConversation = this.xmppConnectionService.find(this.mAccount, Jid.fromString(intent.getExtras().getString("contact")));
            if (this.mConversation == null) {
                return false;
            }
        } catch (final InvalidJidException ignored) {
            return false;
        }
        this.mode = intent.getIntExtra("mode", MODE_MANUAL_VERIFICATION);
        if (this.mode == MODE_SCAN_FINGERPRINT) {
            new IntentIntegrator(this).initiateScan();
            return false;
        }
        return true;
    } else {
        return false;
    }
}
Also used : IntentIntegrator(com.google.zxing.integration.android.IntentIntegrator) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException)

Example 3 with InvalidJidException

use of eu.siacs.conversations.xmpp.jid.InvalidJidException in project Conversations by siacs.

the class XmppConnection method sendBindRequest.

private void sendBindRequest() {
    while (!mXmppConnectionService.areMessagesInitialized() && socket != null && !socket.isClosed()) {
        try {
            Thread.sleep(500);
        } catch (final InterruptedException ignored) {
        }
    }
    needsBinding = false;
    clearIqCallbacks();
    final IqPacket iq = new IqPacket(IqPacket.TYPE.SET);
    iq.addChild("bind", "urn:ietf:params:xml:ns:xmpp-bind").addChild("resource").setContent(account.getResource());
    this.sendUnmodifiedIqPacket(iq, new OnIqPacketReceived() {

        @Override
        public void onIqPacketReceived(final Account account, final IqPacket packet) {
            if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
                return;
            }
            final Element bind = packet.findChild("bind");
            if (bind != null && packet.getType() == IqPacket.TYPE.RESULT) {
                final Element jid = bind.findChild("jid");
                if (jid != null && jid.getContent() != null) {
                    try {
                        if (account.setJid(Jid.fromString(jid.getContent()))) {
                            Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": bare jid changed during bind. updating database");
                            mXmppConnectionService.databaseBackend.updateAccount(account);
                        }
                        if (streamFeatures.hasChild("session") && !streamFeatures.findChild("session").hasChild("optional")) {
                            sendStartSession();
                        } else {
                            sendPostBindInitialization();
                        }
                        return;
                    } catch (final InvalidJidException e) {
                        Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server reported invalid jid (" + jid.getContent() + ") on bind");
                    }
                } else {
                    Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure. (no jid)");
                }
            } else {
                Log.d(Config.LOGTAG, account.getJid() + ": disconnecting because of bind failure (" + packet.toString());
            }
            forceCloseSocket();
            changeStatus(Account.State.BIND_FAILURE);
        }
    });
}
Also used : Account(eu.siacs.conversations.entities.Account) Element(eu.siacs.conversations.xml.Element) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket)

Example 4 with InvalidJidException

use of eu.siacs.conversations.xmpp.jid.InvalidJidException in project Conversations by siacs.

the class AxolotlService method buildSessionFromPEP.

private void buildSessionFromPEP(final AxolotlAddress address) {
    Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Building new session for " + address.toString());
    if (address.equals(getOwnAxolotlAddress())) {
        throw new AssertionError("We should NEVER build a session with ourselves. What happened here?!");
    }
    try {
        IqPacket bundlesPacket = mXmppConnectionService.getIqGenerator().retrieveBundlesForDevice(Jid.fromString(address.getName()), address.getDeviceId());
        Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Retrieving bundle: " + bundlesPacket);
        mXmppConnectionService.sendIqPacket(account, bundlesPacket, new OnIqPacketReceived() {

            @Override
            public void onIqPacketReceived(Account account, IqPacket packet) {
                if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
                    fetchStatusMap.put(address, FetchStatus.TIMEOUT);
                } else if (packet.getType() == IqPacket.TYPE.RESULT) {
                    Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received preKey IQ packet, processing...");
                    final IqParser parser = mXmppConnectionService.getIqParser();
                    final List<PreKeyBundle> preKeyBundleList = parser.preKeys(packet);
                    final PreKeyBundle bundle = parser.bundle(packet);
                    if (preKeyBundleList.isEmpty() || bundle == null) {
                        Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "preKey IQ packet invalid: " + packet);
                        fetchStatusMap.put(address, FetchStatus.ERROR);
                        finishBuildingSessionsFromPEP(address);
                        return;
                    }
                    Random random = new Random();
                    final PreKeyBundle preKey = preKeyBundleList.get(random.nextInt(preKeyBundleList.size()));
                    if (preKey == null) {
                        //should never happen
                        fetchStatusMap.put(address, FetchStatus.ERROR);
                        finishBuildingSessionsFromPEP(address);
                        return;
                    }
                    final PreKeyBundle preKeyBundle = new PreKeyBundle(0, address.getDeviceId(), preKey.getPreKeyId(), preKey.getPreKey(), bundle.getSignedPreKeyId(), bundle.getSignedPreKey(), bundle.getSignedPreKeySignature(), bundle.getIdentityKey());
                    try {
                        SessionBuilder builder = new SessionBuilder(axolotlStore, address);
                        builder.process(preKeyBundle);
                        XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, bundle.getIdentityKey());
                        sessions.put(address, session);
                        if (Config.X509_VERIFICATION) {
                            verifySessionWithPEP(session);
                        } else {
                            FingerprintStatus status = getFingerprintTrust(bundle.getIdentityKey().getFingerprint().replaceAll("\\s", ""));
                            FetchStatus fetchStatus;
                            if (status != null && status.isVerified()) {
                                fetchStatus = FetchStatus.SUCCESS_VERIFIED;
                            } else if (status != null && status.isTrusted()) {
                                fetchStatus = FetchStatus.SUCCESS_TRUSTED;
                            } else {
                                fetchStatus = FetchStatus.SUCCESS;
                            }
                            fetchStatusMap.put(address, fetchStatus);
                            finishBuildingSessionsFromPEP(address);
                        }
                    } catch (UntrustedIdentityException | InvalidKeyException e) {
                        Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error building session for " + address + ": " + e.getClass().getName() + ", " + e.getMessage());
                        fetchStatusMap.put(address, FetchStatus.ERROR);
                        finishBuildingSessionsFromPEP(address);
                    }
                } else {
                    fetchStatusMap.put(address, FetchStatus.ERROR);
                    Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while building session:" + packet.findChild("error"));
                    finishBuildingSessionsFromPEP(address);
                }
            }
        });
    } catch (InvalidJidException e) {
        Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Got address with invalid jid: " + address.getName());
    }
}
Also used : Account(eu.siacs.conversations.entities.Account) IqParser(eu.siacs.conversations.parser.IqParser) UntrustedIdentityException(org.whispersystems.libaxolotl.UntrustedIdentityException) OnIqPacketReceived(eu.siacs.conversations.xmpp.OnIqPacketReceived) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException) SessionBuilder(org.whispersystems.libaxolotl.SessionBuilder) InvalidKeyException(org.whispersystems.libaxolotl.InvalidKeyException) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket) PreKeyBundle(org.whispersystems.libaxolotl.state.PreKeyBundle) Random(java.util.Random)

Example 5 with InvalidJidException

use of eu.siacs.conversations.xmpp.jid.InvalidJidException in project Conversations by siacs.

the class OtrService method verify.

@Override
public void verify(SessionID id, String fingerprint, boolean approved) {
    Log.d(Config.LOGTAG, "OtrService.verify(" + id.toString() + "," + fingerprint + "," + String.valueOf(approved) + ")");
    try {
        final Jid jid = Jid.fromSessionID(id);
        Conversation conversation = this.mXmppConnectionService.find(this.account, jid);
        if (conversation != null) {
            if (approved) {
                conversation.getContact().addOtrFingerprint(fingerprint);
            }
            conversation.smp().hint = null;
            conversation.smp().status = Conversation.Smp.STATUS_VERIFIED;
            mXmppConnectionService.updateConversationUi();
            mXmppConnectionService.syncRosterToDisk(conversation.getAccount());
        }
    } catch (final InvalidJidException ignored) {
    }
}
Also used : Jid(eu.siacs.conversations.xmpp.jid.Jid) InvalidJidException(eu.siacs.conversations.xmpp.jid.InvalidJidException) Conversation(eu.siacs.conversations.entities.Conversation)

Aggregations

InvalidJidException (eu.siacs.conversations.xmpp.jid.InvalidJidException)30 Jid (eu.siacs.conversations.xmpp.jid.Jid)18 Account (eu.siacs.conversations.entities.Account)13 Conversation (eu.siacs.conversations.entities.Conversation)11 AlertDialog (android.app.AlertDialog)4 View (android.view.View)4 Message (eu.siacs.conversations.entities.Message)4 MessagePacket (eu.siacs.conversations.xmpp.stanzas.MessagePacket)4 DialogInterface (android.content.DialogInterface)3 TextView (android.widget.TextView)3 Contact (eu.siacs.conversations.entities.Contact)3 IqPacket (eu.siacs.conversations.xmpp.stanzas.IqPacket)3 SuppressLint (android.annotation.SuppressLint)2 OnClickListener (android.content.DialogInterface.OnClickListener)2 Bundle (android.os.Bundle)2 SpannableString (android.text.SpannableString)2 Pair (android.util.Pair)2 AdapterView (android.widget.AdapterView)2 ListView (android.widget.ListView)2 XmppAxolotlMessage (eu.siacs.conversations.crypto.axolotl.XmppAxolotlMessage)2