I got it working, but.... whats the right way to do this?

So my host is apparently using an older version of jabberd which does not support <stream:features />

When I attempt to connect, I send a <stream:stream … > and get a <stream:stream …> response, but it appears that XIFF is waiting for a <stream:features … /> that will never come.

I have a workaround where I wait for 4 seconds after onConnect and then send an iq get for query jaber:iq:auth and on the callback for that, if digest is present (and for my server it is), I create an iq set passing the username and digest. To get the digest, I needed to modify XMPPConnection.as to add a getSessionID() method and then pass the session ID and password to AuthExtension.computeDigest(…). On the callback from the auth with the digest, I get an iq result when I provide valid credentials and I can send and receive messages.

So, in that regard, this “works” but as it stands, the connection object doesn’t know it’s authenticated, etc.

It helps me to learn XMPP and XIFF to hack this around a bit, but any insight into the valid approach for this would be greatly appreciated.

Thank you,

Peter Richards

Hi Peter: What version of jabberd are you using specifically? Also, are you using the XMPPSocketConnection class or the XMPPConnection class?

I am not sure what version the server is (or even that it is, in fact, jabberd). That’s my best guess based on support and feature request posts at my host. The xmpp server is run by DreamHost so perhaps someone else here may be aware of the server & version information. I’ve sent the question via their support mechanism, but since it’s a “casual question” and not a “people are dying” request, not sure how long it will take them to respond.

I have been using the XMPPSocketConnection. I just tried to switch my code to use XMPPConnection and XMLthat results in: “stream:errorInvalid XML</stream:error>” Likely due to the XMLSocket null termination, but I haven’t looked into it at all, just changed the connection class and tried to log in.

If it is something that you would like to take a look at for XIFF, I’d be happy to PM you with connection information you could use for testing.

Thank you for taking the time to look at my question,

Peter Richards

DreamHost support has responded with: “We are currently running Jabber server version 1.4.3.”

Thanks,

Peter Richards

Hmm … It’s been a long time since I’ve used jabberd, but I’ve definitely been able to make it work. However, that was for XIFF 2.0 and much has changed since then. I will see if I get a chance to try it out myself, but given that my time to work on XIFF is currently pretty limited (in the middle of grad school) I make no promises there.

Have you tried using <flash:stream … instead of <stream:stream … ?

If you manage to figure it out before I do, please let me know.

As I said initially, the version (or perhaps configuration) of jabberd on my server does not send any stream:features tag. I just tried using flash:stream and I get the same situation, I send flash:stream and get a flash:stream but never any features tag.

Looking through the XIFF code for XMPPSocketConnection, the incoming data is handled by bSocketReceivedData(…). Within that method, there is a switch statement on the nodeName. The two nodeNames I care about would be stream:stream or stream:features which call handleStream(…) and handleStreamFeatures(…) in XMPPConnection.

The handleStream(…) method will set the sessionID and domain then check for any children and if a stream:features is found it passes that to handleStreamFeatures(…).

The method handleStreamFeatures(…) will eventually call beginAuthentication() (after configureAuthMechanisms()) and this is the only location I’ve found where beginAuthentication() is called.

Given that a server could send the stream:features... tag as a separate message from the stream:stream... tag, I’m not sure what the best solution here is. You cannot simply assume that if you didn’t get the features tag with the initial stream that there isn’t going to be one. That’s why I used a 4 second timer that kicks off at onConnectSuccess and uses IQ with AuthExtension to complete the login cycle. In my case, to compute the digest I needed the sessionID and so added a public method getSessionID() to XMPPConnection. I suppose I could have subclassed XMPPSocketConnection and added the method and integrated my 4 second timer, etc, then that should protect me from future updates to the XMPPConnection.

One (unrelated) bug I may have found is that in the AuthExtension, if you attempt to set a digest without setting a password first, you get an error. This is due to the set function for digest which does not check myPasswordNode for null prior to calling removeNode on it. The set password method has a similar situation which it handles by first creating an empty node if the node is null, then calling removeNode() and setting the node to null (seems like you could just check for null and only call removeNode() if the node is not null).

I certainly understand your limited time constraints and in the grand scheme of things, integrating some of the newer features (like the TLS/crypto solution posted by Dustin which seems to be highly requested) should probably take precedence. I do have a work-around and so there’s nothing really stopping me. I was more interested if I had simply missed the correct approach to take in my situation.

Thanks,

Peter Richards