XMPP wrong sender address (broadcast serverside)

111 views Asked by At

On messaging from server to all active clients of one user the sender-address is not correctly written.

This is the broadcast-function (serverside):

private void sendAllSessions(final StringBuilder message, final Entity sender,
        final ServerRuntimeContext serverContext, EMailAddress to) {
    EntityImpl recipient = new EntityImpl(to.getLocalName().getLocalName(), to.getDomain().getDomainName(), null);
    Stanza build = createStanza(message, sender, recipient);
    for (SessionContext sessionContext : serverContext.getResourceRegistry().getSessions(recipient)) {
        SessionState state = sessionContext.getState();
        SessionStateHolder stateHolder = new SessionStateHolder();
        stateHolder.setState(state);
        Stanza stanza = new MessageStanza(build);

        LOG.severe("Send xmpp stanza: " + stanza + " from " + stanza.getFrom());
        serverContext.getStanzaProcessor().processStanza(serverContext, sessionContext, stanza, stateHolder);
    }
}

private Stanza createStanza(final StringBuilder strb, final Entity sender, final EntityImpl recipient) {
    try {
        LOG.severe("Create xmpp stanza from " + sender + " (" + sender.getFullQualifiedName() + ") to recipient "
                + recipient + " (" + recipient.getFullQualifiedName() + ")!");
        StanzaBuilder sb = StanzaBuilder.createMessageStanza(sender, recipient, MessageStanzaType.HEADLINE, "html",
                strb.toString());
        Stanza build = sb.build();
        return build;
    } catch (RuntimeException e) {
        StanzaBuilder sb = StanzaBuilder.createMessageStanza(sender, recipient, MessageStanzaType.NORMAL, null,
                strb.toString());
        Stanza build = sb.build();
        return build;
    }
}

This is the logging (serverside):

07-Oct-2021 12:43:58.220 SEVERE [http-nio-80-exec-147] xx.DefaultChat.createStanza Create xmpp stanza from [email protected] ([email protected]) to recipient [email protected] ([email protected])!
07-Oct-2021 12:43:58.222 SEVERE [http-nio-80-exec-147] xx.DefaultChat.sendAllSessions Send xmpp stanza: message.body.Thanks, please wait... from [email protected]
07-Oct-2021 12:43:58.229 FINE [NioProcessor-2] org.apache.vysper.mina.StanzaLoggingFilter.messageSent ><message xmlns="jabber:client" to="[email protected]" from="example.com" type="error"><body>Thanks, please wait...</body><error type="modify"><unknown-sender xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"></unknown-sender></error></message>

The xml human readable is (from server to client):

<message xmlns="jabber:client" to="[email protected]"
    from="example.com" type="error">
    <body>Thanks, please wait...</body>
    <error type="modify">
        <unknown-sender
            xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"></unknown-sender>
    </error>
</message>

My question is why is the XML-Stanza pointing out that the sender (from-field) is the domain only?

2

There are 2 answers

0
Grim On BEST ANSWER

After some debugging I noticed this lines (in org.apache.vysper.xmpp.protocol.ProtocolWorker):

        // make sure that 'from' (if present) matches the bare authorized entity
        // else respond with a stanza error 'unknown-sender'
        // see rfc3920_draft-saintandre-rfc3920bis-04.txt#8.5.4
        if (from != null && sessionContext.getInitiatingEntity() != null) {
            Entity fromBare = from.getBareJID();
            Entity initiatingEntity = sessionContext.getInitiatingEntity();
            if (!initiatingEntity.equals(fromBare)) {
                responseWriter.handleWrongFromJID(sessionContext, stanza);
                return;
            }
        }

So I added a line:

private void sendAllSessions(final StringBuilder message, final Entity sender,
        final ServerRuntimeContext serverContext, final EMailAddress recipientAddress) {
    EntityImpl recipient = new EntityImpl(recipientAddress.getLocalName().getLocalName(),
            recipientAddress.getDomain().getDomainName(), null);
    Stanza build = createStanza(message, sender, recipient);
    for (SessionContext sessionContext : serverContext.getResourceRegistry().getSessions(recipient)) {
        SessionState state = sessionContext.getState();
        SessionStateHolder stateHolder = new SessionStateHolder();
        stateHolder.setState(state);
        Stanza stanza = new MessageStanza(build);
        LOG.severe("Send xmpp stanza: " + stanza + " from " + stanza.getFrom());
        sessionContext.setInitiatingEntity(sender); // THIS LINE IS ADDED
        serverContext.getStanzaProcessor().processStanza(serverContext, sessionContext, stanza, stateHolder);
    }
}

Now it works great:

<message type="headline" from="xxx" to="xxx" xml:lang="html">
<body>Test</body>
</message>
1
Rani Sharim On

This is an error reply from the server, therefor it is the server who sends this message, not a specific user.

If you look at the source code of handling an error:

StanzaBuilder responseBuilder = StanzaBuilder.createDirectReply(stanza, true, "error");

The 2nd parameter is "fromIsServerOnly" parameter:

public static StanzaBuilder createDirectReply(XMPPCoreStanza original, boolean fromIsServerOnly, String type)

And in that case the Stanza which is created strips the from address to be the domain only:

if (fromIsServerOnly)
   newFrom = new EntityImpl(null, newFrom.getDomain(), null);
stanzaBuilder.addAttribute("from", newFrom.getFullQualifiedName());