Playing Casper in Openfire 3.5.0

The next major release of Openfire is going to be 3.5.0 and it will be released on March 6th. Daniel and I are very happy with this new release since it has lots of new features and improvements. Today I will explain how you can be connected but invisible to all or some users. This has been a very popular request in Openfire and in XMPP in general.

A few XMPP extensions were created for invisibility using different strategies (and may be goals). Some of them focused only in blocking your presence to other users while others were blocking incoming/outgoing presences, messages and IQ stanzas. But they have something in common that jeopardized their success. In a nutshell, they not only required server side changes but also client side changes thus making it hard for a user to find a server and a client that supports them.

As of Openfire 3.5.0 there is a very easy way to be invisible and at the same time be able to maintain a one-to-one chat, a group chat or appear visible to the users of your choice or gateways of your choice. The best part of it is that we are not relying on any XMPP extension but just using the XMPP RFC core.

Usually XMPP clients follow these steps while logging in:

  1. Connect to the XMPP server

  2. Secure the connection with TLS

  3. Authenticate with the server using SASL

  4. Send available presence to the server indicating that the client is now publicly available (e.g. 1)

  5. Request their roster

The forth step is actually optional so if clients do not send an available presence then they will be connected to the server but will not appear available/online to other users. Unavailable users cannot get messages from other users unless they made available to them.

When the user decides to appear as online to someone in particular he can send an available presence to that user (e.g.

). Being available to a user means that the user will see you online and you can now chat with that user.

Users that are publicly unavailable can also join a room and have a groupchat. However, if the room is not anonymous (i.e. real JIDs are sent to room occupants) then the other users will know that you are connected and chatting. But probably you won’t care about that unless you wanted to chat without anyone knowing that you are you.

Currently our Spark and Sparkweb clients are not able to join in invisible mode but implementing invisibility this way should be a lot less work for clients than implementing some XMPP extension.

dont forget to make a “disable” switch for that:) there is no place for “caspers” in corporate environment:)

On the contrary, wroot, we have been eagerly anticipating Casper for our corporate environment. Many of our employees would like to be available at certain times for fellow employees but not available for students, and vice versa.

Daniel and David, when do you think Spark and SparkWeb will be able to join in invisible mode?

SparkWeb should support it “soonish”. I’m going to need to implement it for something else, but I still need to work out the UI for it, as well as a few other issues. No promises of course

How would you go invisible after having been online? Would you need to log out and then log back in? Or would you send presence type=‘unavailable’ and then send directed presence stanzas? (But that would not help you receive messages, because the server would think you’re offline.) Note also that you would not receive roster updates while in invisible mode (because according to rfc3921bis you’re not an “interested resource”). In fact you should be able to do this right now in all XMPP servers, since it’s just XMPP according to RFC 3920 and RFC 3921, so it’s not a special feature in Openfire. Whether all servers and clients enable you to do this is another matter…

Hrm. Good points Peter. I imagine the scenario you described is exactly how that would play out. Of course, going unavailable implies a number of things. Many components watch for that and trigger logout type events. Spark actually does something semi-similar with the IM transports where it sends directed presences but does not add the transport to the user’s roster. It’s “kind of a hack”, but it does the trick for now. I’ve occasionally tried to write up a concept for accomplishing what we’ve done with that modification in a standard way. That has yet to come to be as I keep running into “hrm, crap, didn’t think about that scenario”. Anyway, while I always thought that old XEP for invisibility was easier, it also was confusing and ugly. The newer one is more complex but doable. I haven’t seen much adoption of it though. Do you have any thoughts as to why it hasn’t been adopted? One of the typical chicken and the egg scenarios?

Also I don’t really see a statement about this feature being unique to Openfire. Did I miss that?

It’s not clear to me that this is even a server feature. According to RFC 3920/3921, if you log in but don’t send initial presence, then you can send directed presence. If you send unavailable presence but don’t close the stream, then you still have a session, so you should be able to send directed presence. Both of these essentially enable you to be invisible. But I don’t think that clients do things this way (they probably send unavailable presence and then immediately close the stream). So I think that this approach to invisibility is really a client feature, not a server feature (if it’s a new feature in Openfire, how did Openfire behave before this “feature” was added?). It would be interesting to test this against a number of different servers. Maybe this is the right approach to invisibility (it’s compliant with the core RFCs, so that’s good, but it doesn’t enable you to receive roster updates unless we modify the definition of “interested resource” in rfc3921bis). I would love to have a better definition of invisibility, but I’m not yet sure if this is the right approach. I grant you that it has possibilities.

Well I can tell you pre-3.5.0 that it didn’t work with Openfire. One might call that a bug, or one might call that a new feature for Openfire. hehehe Either way it’s new for Openfire to have it behave properly. =) I must admit I don’t know the details of why it didn’t work before though.

As for roster updates, I must admit I never read that part of the RFC. I always thought you indicated that you were an interested resource for the roster updates via your initial jabber:iq:roster request. (in other words, if I ask for my roster, I must be interested in it)

Well, in part the concept of an “interested resource” is tied to the connection between rosters and presence. When you are an interested resource, you receive both roster updates and presence subscription requests. If you are unavailable, you won’t receive presence subscription requests, so it may seem strange to receive roster updates. Maybe we could overcome that by saying the unavailable resource could send directed presence to its server, but such behavior is undefined right now. Something to ponder further…

Hey Peter and Daniel,

Lots of messages to reply (since I last checked the blog post). Daniel, I don’t think this is a hack but a way, without breaking any rule, to achieve invisibility based on the requirements I heard from people in the community. Before Openfire 3.5.0 it was possible to join a group chat room while being unavailable but one-2-one chat was not working as I wanted it to work.

The XMPP RFC says that once a client sent an available presence then it’s available for communication. My initial reading of that spec was that unless a client sends an available presence he will not receive messages from anyone. However, I then heard another interpretation of the spec were clients should be allowed to receive messages from entities that previously received a directed presence. This new interpretation is what we implemented for the new 3.5.0 release.

Peter, I agree that this is not the best place to discuss XMPP specifications but since we started it here let me clarify my position and we can then move it to the XMPP mailing list.

How would you go invisible after having been online? Would you need to log out and then log back in? Or would you send presence type=‘unavailable’ and then send directed presence stanzas?

My understanding when people talk about invisibility is that they do not want to appear (publicly) online. I also think that they want to log into the server in that mode instead of briefly appearing online to then go invisible. They may want to appear online to some people but not all. So based on this ideas I think that invisible is like being (publicly) unavailable. To answer your question, I think that if a user once sent an available presence (i.e. was publicly available) and he then wants to go invisible then he should send an unavailable presence. That means that he will be seen publicly offline and be treated as an offline resource (i.e. will not get messages) unless he then sends new directed presences. In fact, servers and clients should support the case of sending an unavailable presence and remain connected and maybe to later disconnect or send some directed presences or become publicly available.

Note also that you would not receive roster updates while in invisible mode (because according to rfc3921bis you’re not an “interested resource”).

IMO, we may want to reconsider this in the spec. I think that if a client sent an iq:roster packet then the client is interested in his roster and therefore should get roster updates. If you are not interested in your roster do not ask it and you will also not get roster updates. Regarding getting presence updates I see that the RFC says that the server should send them once the client sent his initial available presence. This makes sense to me although I would clarify that it does not only apply to initial presences but just when declaring the client as available (by sending an available presence).

Note: I agree that the spec needs to worry about consistencies like this case with the roster but in this particular case I think that in practice it’s a marginal case where a user needs to be connected from many resources, change his roster and be invisible.

In fact you should be able to do this right now in all XMPP servers, since it’s just XMPP according to RFC 3920 and RFC 3921, so it’s not a special feature in Openfire.

I don’t think I said or implied this was a special feature in Openfire. I even said that this was possible by following the XMPP RFC (with no XEP). And as you can see IMHO this is the way to go for implementing invisibility.

Thanks,

– Gato

Hi Gato, this is definitely worth thinking about. So I’ll do some thinking. I don’t like to modify the core specs more than necessary, but sometimes it’s necessary…

I don’t believe I called it a hack. I called the Spark functionality a hack.

Hey Darren,

You are correct that you can use privacy lists for implementing invisibility. However, most of the clients out there do not support privacy lists or the UI is not very simple to use. Of course they could make it simpler but I never saw one do that.

– Gato

Hi,

for me this sounds like a weak solution, one can still probe the client version or time using XMPP to detect if one is online and invisible.

But it would be very nice if one would fix JM-1013 so one could use Privacy Lists to manage the privacy lists. Better client support to mange privacy lists would be great.

LG