GSSAPI/Kerberos Authentication

Ive been toying with GSSAPI auth and am making progress, but not there quite yet.

The code in SASLAuthentication is well suited for GSSAPI already, just need to know when to advertise it. For my purposes, I just have it always advertise GSSAPI before PLAIN.

The first problem is that Java needs to know how/where to find the Kerberos information. In the sample app’'s Sun provides, you do this on the commandline and with a config file like so:

java -Djava.security.auth.login.config= SampleServer

Then in that file you speicify the options you want:

com.sun.security.jgss.accept {

com.sun.security.auth.module.Krb5LoginModule required storeKey=true keyTab="/etc/jabber.keytab" doNotPrompt=true useKeyTab=true realm=“EXAMPLE.COM” principal=“xmpp/hostname.example.com@EXAMPLE.COM” debug=true;

};

With my lack of java experience I dont know how to specify these things elsewhere- like in the wildfire config. For now Ill just add it to the commandline on the start. So, if anyone knows how to supply those config details via another means, Im interested in hearing.

Also, Im thinking there will be a desire at some point to kerberos principals that DONT match jabber user ids. That way someone with a principal jd87235@EXAMPLE.COM can have a jabber id of john.doe@example.com. Has anyone looked at this possibility at all? Does the XMPP protocol even support this? This will become more useful/needed if cross-realm authentication is added, where you might have two people with the same username, but different principals authenticating to the server. For example, john@EXAMPLE.COM and john@CORPORATE.EXAMPLE.COM might be two different people, but both need to authenticate to the jabber server; maybe one gets john.doe@example.com and the other gets john.johnson@example.com. This isnt real high on my needs right now as our realms dont have duplicate user names for seperate people, but this is a pretty common feature with kerberos enabled software systems. It might even be useful for role based accounts, having john@EXAMPLE.COM log in as the user support@example.com for example.

Hi Jay,

my first idea is to set the property (hard-coded) in a method before the Kerberos classes are initialized. So this value could be put inside wildfire.xml and then be read and set while Wifi is starting.

You could also create a vmoptions file, like described in “%programfiles%\wildfire\documentation\install-guide.html” section Custom Parameters and add the line there, but this nearly the same as using the command line.

LG

I think youve lost me. Im not much of a Java person, and only really used it like 4 years ago for a while

I assume I need to set these properites before the doAuthenticate method, but HOW to set these properties escapes me. Are properties defined on the command line just public fields to (static?) objects? It dosnt seem like it, at least trying the obvious dosnt work:

java.security.krb5.debug = true;

(fails at compile time not finding the java.security.krb5 object)

Someone just passed this along to me:

http://www.irbs.net/internet/cyrus-sasl/0508/0004.html

This is going to make it hard to test some of the various clients out there. As of right now, I dont know any GSSAPI enabled clients that dont use Cyrus SASL. Whats the likelyhood of getting something like this into Spark for testing? At least it would be using the same implementation on client and server then.

Anyone know of other GSSAPI enabled clients?

System.setProperty(“java.security.auth.login.config”, “/foobar”); should do it.

Right on!

Now for the hard part. java.security.auth.login.config expects its own config file. Do you know any tricks to have it not use its own config file?

Ok, I have a java client and server that does a GSSAPI auth to eachother, and for the purposes of the test it looks like xmmp, though it dosnt really parse xml. The idea is to use the sample client to copy/paste into a wildfire network session to test with. So, I started putting the compoents into the SASLAuthentication object, and I get this error:

javax.security.sasl.SaslException: GSS initiate failed Caused by GSSException: DerInputStream.getLength(): lengthTag=66, too big.

at com.sun.security.sasl.gsskerb.GssKrb5Server.evaluateResponse(GssKrb5Server.java :159)

at org.jivesoftware.wildfire.net.SASLAuthentication.doHandshake(SASLAuthentication .java:201)

at org.jivesoftware.wildfire.net.SocketReader.authenticateClient(SocketReader.java :315)

at org.jivesoftware.wildfire.net.SocketReader.readStream(SocketReader.java:276)

at org.jivesoftware.wildfire.net.SocketReader.run(SocketReader.java:119)

at java.lang.Thread.run(Thread.java:595)

Caused by: GSSException: DerInputStream.getLength(): lengthTag=66, too big.

at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:318)

at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:246)

at com.sun.security.sasl.gsskerb.GssKrb5Server.evaluateResponse(GssKrb5Server.java :137)

… 5 more

Lline 201 is where the first ss.evaluateResponse() is called, but instead of an empty byte array, it passes the intial GSSAPI token.

Now, Im having trouble tracking down the exact meaning of the error, but I think it means the intial token is too large. I couldnt find anything with a quick search, but does Wildfire set a MAX_BUFFER value (or anything like it)? Im using the same objects in my sample server and it works fine, so I have a feeling this has to do with some system property/envrionment/etc that wildfire modified.

Hmm… the length problem is something else. It has something to do with the Base64 encode/decode process. Assume for the moment that doc.getTextTrim() has a Base64 encoded token. If I do this:

Log.warn("In:\n–


\n"doc.getTextTrim()"\n–


\n");

Log.warn("Out:\n–


\n"StringUtils.encodeBase64( StringUtils.decodeBase64( doc.getTextTrim().getBytes(CHARSET) ).getBytes(CHARSET) )"\n–


\n");

I should get the same result for both In and Out in the log, right? Well, Im not, and Im not certain why. Ive tried playing around with the CHARSET but nothing really changes. Whats going on here?

Sample log output (its mostly binary):

2006.02.23 14:55:14 In:


YIICFgYJKoZIhvcSAQICAQBuggIFMIICAaADAgEFoQMCAQ6iBwMFAAAAAACjggEdYYIBGTCCARWgAwIB BaEQGw5TTFVTSFBVUElFLkNPTaIqMCigAwIBAKEhMB8bBHhtcHAbF2hlYmUuaW50LnNsdXNocHVwaWUu Y29to4HPMIHMoAMCARChAwIBA6KBvwSBvAKHJIbLqJwXqRLw/F1oYLdo0ReViJWpjUe0PfZoAjmYK6Z7 q0aKvofGOrRDM7/5U/4ATy1vziKI1wcnpqsUVYBwWvFM371exC6I5UnzNNi112IirqNuXNC3dsQfnBUwk/icouetARF3XNzoETwx5gg7uBdJM5BBZRKasjQ/px5OY5RZbsAHXivRN2A6cdmKWvsIbGbJGcmG0lyiume/8Um9HD74/hw49qsGbjhDgHxWvMuLNUbr7GPpIHKMIHHoAMCARCigb8Egbyk0nO9yOkO68/2N5mx560jWPePB0HHphqZme8SKvSKlrw3QfMkSwcKg Mg6VFVCRUpQJa/e3jp9W8RC9l1Im9cpVORWUOFZSfYM2FjLqFXfJI5BtLHqCfafqITqtcACLeKSx8NBbA9yG 6p2K10pyhLsn3F0Zw3VjW7/6G6FvS9ouuWfuWpT9VXfb8cYo+eqxD8N5XXt5XmrhXfuGAUlvLUicOEB4 /XUMApQm54cBqeXdA7lP41uoo5c3nHbg==


2006.02.23 14:55:14 Out:


YMKCAhYGCSrChkjChsO3EgECAgEAbsKCAgUwwoICAcKgAwIBBcKhAwIBDsKiBwMFAAAAAADCo8KCAR1h woIBGTDCggEVwqADAgEFwqEQGw5TTFVTSFBVUElFLkNPTcKiKjAowqADAgEAwqEhMB8bBHhtcHAbF2hl YmUuaW50LnNsdXNocHVwaWUuY29twqPCgcOPMMKBw4zCoAMCARDCoQMCAQPCosKBwr8EwoHCvALChyTC hsOLwqjCnBfCqRLDsMO8XWhgwrdow5EXwpXCiMKVwqnCjUfCtD3DtmgCOcKYK8Kme8KrRsKKwr7Ch8OG OsK0QzPCv8O5U8OAE8tb8OOIsKIw5cHJ8O6wprCrFFWAcOBa8OFM37DtXsQwrojwpUnw4zDk2LDl13CiMKKwrrCjcK7w6XD jQt3bEHDucOBUwk/wonDii56w5ARF3XDjcOOwoETw7sMecKCDsOuBcOSTMOkEFlEwqbCrMKND8Opw4fC k8KYw6UWW8KwAcOXworDtE3Dm8OgOnHDmcKKWsO7CGxmw4kZw4nChsOSXMKiwrpnwr/DsUnCvRww7jDvhw4w7bCqwZuOEPCgHxWwrzDi8KLNUbDq8O7wrHCj8KkwoHDijDCgcOHwqADAgEQwqLCgcK/BMKB wrzCpMOSc8K9w4jDqQ7Dq8OPw7Y3wpnCscOnwq0jWMO3wo8HQcOHwqYawpnCmcOvEirDtMKKwpbCvDdB w7MkSwcKwoDDiDpXw6FVCRUpQMKWwr97eMOpw7VvEQvDmXUib1zCpVPCkVlDwoVlJ8OYM2FjLsKhV3zC kjkGw5LDh8KoJ8OafsKiE8Kqw5cACMK3wopLHw0FwrA9w4huwqnDmMKtdMKnKEvCsn3DhcORwpw3VjXC u8O/wqHCuhbDtMK9wqLDq8KWfsOlwqlPw5VXfcK/HGLCj8KewqsQw7w3wpXDl8K3wpXDpsKuFcOfwrhg FMKWw7LDlMKJw4PChAfCj8OXUMOAKUJueHAawp5dw5A7wpTDvjXCusKKOXN5w4du


Slush,

It could have something to do with the actual base64 implementation. Alex didn’‘t have kind things to say about it when he was implementing IBB file transfer. There’'s a different impl of base64 in Smack SVN (in the file transfer package). Maybe you should try that one out?

Regards,

Matt

I was looking at the algorithm too, and I think there might be some bugs in it, but its hard to tell. Looks like you are using the same one I was: http://iharder.sourceforge.net/base64/

Ill try swapping out the functions in StringUtils to see if that fixes the problem.

Ok, Im showing my ignorance about Ant (never used it before). If I want to add a new class to the package org.jivesoftware.util (Base64 and its inner classes) what do I need to do so I can use that class elsewhere (like in SASLAuth)?

I added the Base64.java, and I see that it gets compiled (the .class files make it into the target directory) but when it tries to compile code referencing it I get an unresovled symbol error on that class. Do I need to tell something about the dependancy? Or am I missing something else?

Hi Jay,

maybe you can copy (and rename) the methods into an existing java file, so you don’'t have to care about your new file. So you can be sure that a new java file is not the problem and you can give it a try right now.

LG

I got it working! GSSAPI/Kerberos Auth in Wildfire is a reality for me right now. I just dont have any real clients at this time. I guess its time to start patching gaim…

When I get things more cleaned up Ill post code. Really, only minor changes were needed, most of the support was already there with SASL.

When I get things more cleaned up Ill post code.

Really, only minor changes were needed, most of the

support was already there with SASL.

What about Pandion? Will your code be compatible with their NTLM stuff, or is that totally different?

Regards,

Matt

I have to say, I have no idea about NTLM or how it works. I dont have an envrionment to test NTLM either (all Unix). I was under the impression that Active Directory uses Kerberos in an accessable way, so I suppose in theory it will work, but I cant say for certain. If someone has an envionment to let me test in, Im willing to take a look though

Well, I did a little research. For Windows Server 2003, at least, Kerberos is used extensively, so in theory it should work. Some possible roadblocks:

  • Java not knowing how to access the keytab

  • Java not understanding the encryption types

  • Microsoft modifying kerberos just enough to break compatibility with stock MIT kerberos

NTLM was replaced by kerberos as of Win2K, so Im optimistic that it will work correctly if a keytab can be generated in a way Java can read.

If you take a look at this article: http://www.microsoft.com/technet/prodtechnol/windows2000serv/deploy/confeat/kerb eros.mspx

At the very bottom they talk about compatability with MIT kerberos, and most things seem to test out ok. Ive not been able to figure out how one would generate a keytab for a service principal by hand, so that might be a stumbling block too.

MS really wants people to use their own SSP interface instead of GSSAPI. “The two interfaces are compatible and similar.”

To get SASL-NTLM support on a windows server, you could try using my SASL-SSPI framework . It’‘s basically just a bridge between Java’‘s SASL APIs and Windows’’ SSPI APIs. With the changes made to wildfire by slushpupie it should be a matter of drop in and go. Wildfire might need to be tweaked to announce NTLM, but I’‘ve successfully tweaked Pandion to try NTLM auth even though it’'s not announced in the feature list.

http://norman.rasmussen.co.za/dl/sasl-sspi/

Can you send me a copy of the patches too please. (using the email address in my profile)

The keytab should be really easy to generate - you just use the ktab utility as in http://edocs.bea.com/wls/docs81/secmanage/sso.html