Commit 637cc817 authored by Dele Olajide's avatar Dele Olajide

Section 8.5.1 of RFC 6121 - No such user

This cannot be enforced strictly for openfire IQ handlers to process packets for custom namespaces. I am modifying the original fix to exclude IQ handlers and also check for anonymous users.
parent bcacd508
...@@ -200,7 +200,7 @@ public class IQRouter extends BasicModule { ...@@ -200,7 +200,7 @@ public class IQRouter extends BasicModule {
* *
* Once an IQ result was received, the listener will be invoked and removed * Once an IQ result was received, the listener will be invoked and removed
* from the list of listeners.<p> * from the list of listeners.<p>
* *
* If no result was received within one minute, the timeout method of the * If no result was received within one minute, the timeout method of the
* listener will be invoked and the listener will be removed from the list * listener will be invoked and the listener will be removed from the list
* of listeners. * of listeners.
...@@ -221,19 +221,19 @@ public class IQRouter extends BasicModule { ...@@ -221,19 +221,19 @@ public class IQRouter extends BasicModule {
* is sent to the server itself and is of type result or error. This is a * is sent to the server itself and is of type result or error. This is a
* nice way for the server to send IQ packets to other XMPP entities and be * nice way for the server to send IQ packets to other XMPP entities and be
* waked up when a response is received back.<p> * waked up when a response is received back.<p>
* *
* Once an IQ result was received, the listener will be invoked and removed * Once an IQ result was received, the listener will be invoked and removed
* from the list of listeners.<p> * from the list of listeners.<p>
* *
* If no result was received within the specified amount of milliseconds, * If no result was received within the specified amount of milliseconds,
* the timeout method of the listener will be invoked and the listener will * the timeout method of the listener will be invoked and the listener will
* be removed from the list of listeners.<p> * be removed from the list of listeners.<p>
* *
* Note that the listener will remain active for <em>at least</em> the * Note that the listener will remain active for <em>at least</em> the
* specified timeout value. The listener will not be removed at the exact * specified timeout value. The listener will not be removed at the exact
* moment it times out. Instead, purging of timed out listeners is a * moment it times out. Instead, purging of timed out listeners is a
* periodic scheduled job. * periodic scheduled job.
* *
* @param id * @param id
* the id of the IQ packet being sent from the server to an XMPP * the id of the IQ packet being sent from the server to an XMPP
* entity. * entity.
...@@ -243,7 +243,7 @@ public class IQRouter extends BasicModule { ...@@ -243,7 +243,7 @@ public class IQRouter extends BasicModule {
* @param timeoutmillis * @param timeoutmillis
* The amount of milliseconds after which waiting for a response * The amount of milliseconds after which waiting for a response
* should be stopped. * should be stopped.
*/ */
public void addIQResultListener(String id, IQResultListener listener, long timeoutmillis) { public void addIQResultListener(String id, IQResultListener listener, long timeoutmillis) {
resultListeners.put(id, listener); resultListeners.put(id, listener);
resultTimeout.put(id, System.currentTimeMillis() + timeoutmillis); resultTimeout.put(id, System.currentTimeMillis() + timeoutmillis);
...@@ -327,16 +327,7 @@ public class IQRouter extends BasicModule { ...@@ -327,16 +327,7 @@ public class IQRouter extends BasicModule {
return; return;
} }
// RFC 6121 8.5.1. No Such User http://xmpp.org/rfcs/rfc6121.html#rules-localpart-nosuchuser if (isLocalServer(recipientJID)) {
// If the 'to' address specifies a bare JID <localpart@domainpart> or full JID <localpart@domainpart/resourcepart> where the domainpart of the JID matches a configured domain that is serviced by the server itself, the server MUST proceed as follows.
// If the user account identified by the 'to' attribute does not exist, how the stanza is processed depends on the stanza type.
if (recipientJID != null && recipientJID.getNode() != null && serverName.equals(recipientJID.getDomain()) && !userManager.isRegisteredUser(recipientJID.getNode()) && (IQ.Type.set == packet.getType() || IQ.Type.get == packet.getType())) {
// For an IQ stanza, the server MUST return a <service-unavailable/> stanza error to the sender.
sendErrorPacket(packet, PacketError.Condition.service_unavailable);
return;
}
if (isLocalServer(recipientJID)) {
// Let the server handle the Packet // Let the server handle the Packet
Element childElement = packet.getChildElement(); Element childElement = packet.getChildElement();
String namespace = null; String namespace = null;
...@@ -386,6 +377,16 @@ public class IQRouter extends BasicModule { ...@@ -386,6 +377,16 @@ public class IQRouter extends BasicModule {
} }
} }
else { else {
// RFC 6121 8.5.1. No Such User http://xmpp.org/rfcs/rfc6121.html#rules-localpart-nosuchuser
// If the 'to' address specifies a bare JID <localpart@domainpart> or full JID <localpart@domainpart/resourcepart> where the domainpart of the JID matches a configured domain that is serviced by the server itself, the server MUST proceed as follows.
// If the user account identified by the 'to' attribute does not exist, how the stanza is processed depends on the stanza type.
if (recipientJID != null && recipientJID.getNode() != null && serverName.equals(recipientJID.getDomain()) && !userManager.isRegisteredUser(recipientJID.getNode()) && sessionManager.getSession(recipientJID) == null && (IQ.Type.set == packet.getType() || IQ.Type.get == packet.getType())) {
// For an IQ stanza, the server MUST return a <service-unavailable/> stanza error to the sender.
sendErrorPacket(packet, PacketError.Condition.service_unavailable);
return;
}
ClientSession session = sessionManager.getSession(packet.getFrom()); ClientSession session = sessionManager.getSession(packet.getFrom());
boolean isAcceptable = true; boolean isAcceptable = true;
if (session instanceof LocalClientSession) { if (session instanceof LocalClientSession) {
...@@ -473,20 +474,20 @@ public class IQRouter extends BasicModule { ...@@ -473,20 +474,20 @@ public class IQRouter extends BasicModule {
Log.warn("Error or result packet could not be delivered " + packet.toXML()); Log.warn("Error or result packet could not be delivered " + packet.toXML());
} }
} }
/** /**
* Timer task that will remove Listeners that wait for results to IQ stanzas * Timer task that will remove Listeners that wait for results to IQ stanzas
* that have timed out. Time out values can be set to each listener * that have timed out. Time out values can be set to each listener
* individually by adjusting the timeout value in the third parameter of * individually by adjusting the timeout value in the third parameter of
* {@link IQRouter#addIQResultListener(String, IQResultListener, long)}. * {@link IQRouter#addIQResultListener(String, IQResultListener, long)}.
* *
* @author Guus der Kinderen, guus@nimbuzz.com * @author Guus der Kinderen, guus@nimbuzz.com
*/ */
private class TimeoutTask extends TimerTask { private class TimeoutTask extends TimerTask {
/** /**
* Iterates over and removes all timed out results.<p> * Iterates over and removes all timed out results.<p>
* *
* The map that keeps track of timeout values is ordered by timeout * The map that keeps track of timeout values is ordered by timeout
* date. This way, iteration can be stopped as soon as the first value * date. This way, iteration can be stopped as soon as the first value
* has been found that didn't timeout yet. * has been found that didn't timeout yet.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment