Presence probes and components

I’m trying to create an external component that probes the presence information for a given user on behalf of another user. I created an external component with the Whack library and am using the Tinder Presence class. I am having difficulty working out firstly if

a) this is possible

b) what the from address should be

I’m using the following snippet to test things

Presence presence = new Presence(Presence.Type.probe);
mgr.sendPacket(component, presence);

The two users adb@atacama and adb_l@atacama have exchanged contacts so can see each other’s presence. The component name is roster.atacama

When adb@atacama is logged in with Spark client and adb_l is not logged in, if I set

from = adb_l@atacama/roster

to = adb@atacama

I get the following in Openfire’s debug.log

2011.06.09 10:05:50 RoutingTableImpl: Failed to route packet to JID: adb_l@atacama/roster packet: Online1</presen ce>

This makes some sense as adb_l is not logged in, so there’s no way to send it to that user although the use of the full JID is not part of RFC 6121. If I set

from = adb_l@atacama

to = adb@atacama

then I get nothing in debug.log and no response in my component. This I don’t understand, but there seems to be an interoperability issue here which is mentioned in rfc 6121, section 4.3 which talks about using the bare JID for probes, whereas 3921 used the full JID. Still, if I set

from = roster.atacama

to = adb@atacama

then I get nothing in debug.log, but my component receives a presence error response

<presence type="error" to="roster.atacama" from="adb@atacama">
  <error code="403" type="auth">
    <forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>

That also makes some kind of sense as the component is not in adb@atacama’s roster. So, I feel the answer is (a) that this is not possible, but would like a definitive answer and if not, how can my component find out the presence status between a pair of JIDs? One thing I saw is pre-approvals (rfc section 3.4) but I don’t really want to force the component to be in the user’s roster.

I would really appreciate anyone with any experience out there that can comment on this.



Am I really posing such a tricky question Would really appreciate it if someone could throw some light!


I’m not sure that I fully understand what you’re trying to do, but from your description, the behavior that’s logged does make sense:

If an XMPP entity (such as a user, but a component is an entity too) is not subscribed to the presence information of another entity, it is not allowed to do probes. This most likely is the cause of the auth/forbidden error that your component receives. The workaround is simple, as you already identified: make sure that the component is subscribed to the presence of the entities that it is trying to probe.

A warning: Did you consider the potential consequences of your setup? If your network is an IM-provider, exposing presence this way might allow for presence information being leaked to users that should not get this information.

You could create a custom component that runs in Openfire (a Plugin that implements the Component interface, for example). You could use this to tap into the internals of Openfire, and get presence information from there. Not a real elegant or portable solution, but it could do the trick.

Thanks for the comments Guus. My external app wants to feed presence info to a third party mail and calendar client. When the client wants to open a meeting or mail item, it can then see the presence information for the sender/recipients. Rather than implementing the XMPP stuff in the client (various reasons), we are trying to see if can be done by the trusted server side component instead.

I got the impression from RFC6121 (sec. 4.3), that presence probes are sent on behalf of a user by the user’s server, so clearly a server can do probes on behalf of two users. Reading XEP-0114 (component protocol) it says that “An external component is commonly trusted to do things that clients cannot…”, so was under the impression that a probe would be something allowed.

Admittedly, the specs are not clear on what components can do as the XEP is marked as Historical and there does not seem to be something to replace/update it. I have gradually been coming to the conclusion that the plugin approach is the only real solution, as you say, not elegant or portable

However, is there any reason (from the specs) that says clearly tells you that the trusted component should **not **be able to make those probes. If not, could this be something that I could enhance in the base code. Presumably the current implementation is just looking at the session and checking from = session owner. I imagine (without checking) that this change might be quite trivial to allow.