On Tue Oct 23 08:25:59 2007, Jacob Wright wrote:
I'm working on the DIGEST-MD5 SASL authentication and feel like I'm doing it perfectly, but my server is telling me I've got an incorrect auth for theright username and password.
Now you know one of the reasons that the IETF is deprecating it. :-/
var dataStr:String = bytes.readUTFBytes(bytes.bytesAvailable);
Hmmm... DIGEST-MD5 isn't UTF-8, by default. (It's iso-8859-1, I think, due to HTTP-isms in it). This will probably work, though.
// transcode the string into an object var data:Object = stringToObject(dataStr);
What does this actually do?
obj["digest-uri"] = "xmpp/" + (conn.domain || conn.host);
Actually, this should probably be:
if conn.domain != conn.host {
obj["serv-name"] = conn.domain
obj["digest-uri"] = "xmpp/" + conn.host + "/" + conn.domain
} else {
obj["digest-uri"] = "xmpp/" + conn.host
}
or something similar. Although I note you have one or other
populated, by the looks of things, so you'll need to adjust to fit.
Except this is one of those areas that's probably ignored, so maybe just stick with whatever seems to work. To be honest, you can probably send utter rubbish here as long as you get the service right. (I've seen failures to to the wrong service name used, but never due to the wrong host. My bet is that nobody cares.)
It doesn't seem very likely that you want to be messing with algorithm. It's not present in RFC2831, after all, and has no effect unless you're doing something other than qop=auth.if (data.algorithm) obj.algorithm = data.algorithm;
qop absent, or qop=auth, are the same thing. You don't need to be conditional on whether the remote end gives you a choice. (Unless you're trying to do auth-int).obj.nc = "00000001"; if (data.qop) obj.qop = "auth";
obj.cnonce = conn.generateId();
This isn't secure enough, but it should still work, of course.
Ooops - does MD5.hash() return a hex digest or a binary one? You want a binary digest here.var a1:String, a2:String;a1 = MD5.hash(obj.username + ":" + obj.realm + ":" + password) + ":" +obj.nonce + ":" + obj.cnonce;
a2 = "AUTHENTICATE:" + obj["digest-uri"]; var response:String; if (obj.qop)response = MD5.hash(MD5.hash(a1) + ":" + obj.nonce + ":" + obj.nc + ":" +obj.cnonce + ":" + obj.qop + ":" + MD5.hash(a2));
All the hashes here are hex strings, and need to be in lower case.Response does vary based on qop, but you should always be using qop=auth anyway, which is also the default if not present.
And again, what is this doing? Bear in mind that if it's some convenient built-in that produces output that's similar to DIGEST-MD5's syntax, this may not be quite right.var resultStr:String = objectToString(obj);
Hope this gives you some pointers, anyway. I'm pretty sure it'll be down to the distinction between H() and HEX(H()).
http://svn.dave.cridland.net/svn/projects/infotrope/python/infotrope/sasl.py contains an implementation of DIGEST-MD5 in Python, if that helps. The method "gen_hash" does the serious magic.
Dave. -- Dave Cridland - mailto:[EMAIL PROTECTED] - xmpp:[EMAIL PROTECTED] - acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/ - http://dave.cridland.net/ Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade
