Kerberos broken after upgrading from Java6 to Java7
Asked Answered
S

3

11

I have a working application using the spring-security kerberos extension, running on jboss, running java 6.

I'm in the process of upgrading my jvm from java 6 to java 7. When I do that, using the same codebase and the same keytab that worked on java 6, I now receive an error when using java 7.

I consistently receive: java.security.PrivilegedActionException: GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - RC4 with HMAC)

I've tried to regenerate the keytab with the different /crypto options that have been described in other forums to no avail.

I have debugged the java 7 code and indeed, the classes that deal with reading the keytab on startup changed from 6 to 7. Could it be that my keytab isn't being read into the app correctly anymore? Some of the debug messages that I see on startup using Java6 don't appear anymore in 7, but I can't tell if that's by design or if that indicates something else is in play? Has anybody else had problems upgrading from 6 to 7 and had their kerberos integration break on them? Any advice?

With spnego and kerberos debug logging on for startup, my log shows:

2012-12-10 10:29:30,886  Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is jndi:/localhost/docfinity/WEB-INF/classes/config/common/security/http-docfinity.keytab refreshKrb5Config is false principal is HTTP/[email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false
2012-12-10 10:30:26,322  principal is HTTP/[email protected]
2012-12-10 10:30:29,794  Will use keytab
2012-12-10 10:30:29,807  Ordering keys wrt default_tkt_enctypes list
2012-12-10 10:30:29,821  Config name: C:\Windows\krb5.ini
2012-12-10 10:30:29,827  Using builtin default etypes for default_tkt_enctypes
2012-12-10 10:30:29,832  default etypes for default_tkt_enctypes:
2012-12-10 10:30:29,837   17    aes128-cts-hmac-sha1-96
2012-12-10 10:30:29,839   16    des3-cbc-sha1-kd
2012-12-10 10:30:29,842   23    rc4-hmac
2012-12-10 10:30:29,846   1     des-cbc-crc
2012-12-10 10:30:29,849   3     des-cbc-md5
2012-12-10 10:30:29,851  .
2012-12-10 10:30:29,855  Commit Succeeded 

One other question - you'll see it's trying to read C:\Windows\krb5.ini. I don't have such a file on my server. Do I need one? I didn't have one with java 6 either and that worked.

aaron

Suburban answered 10/12, 2012 at 15:0 Comment(24)
What crypto does your keytab support? This must be the problem. The listed etypes are supported by JGSS but your keytab requires ArcFour to respond to the AS.Conrado
Are you asking what /crypto I used when generating my keytab? If that is the question, then I've tried a good number of them - specifying RC4-HMAC specifically and also using the ALL option. I'm not sure that's what you're asking though, is it?Suburban
Yes, that is exactly my question. did you enable -Dsun.security.krb5.debug=true to see Kerberos debug output?Conrado
Michael - first off, thanks for the help - I need it. Ugh. Secondly, I have enabled that debug=true setting. Is there something that I can provide that would give you any insight? The snippet in the original message is what I see on startup. Do you want some of the log that I see during authentication as well?Suburban
You did enable for the LoginModule but not for all Kerberos-related classes. This is a difference. Add that environment property to your JBOss startup env.Conrado
I have the following 2 lines in my startup script though, one of which includes the debugging you talked about... wrapper.java.additional.3100=-Dsun.security.krb5.debug=true wrapper.java.additional.3200=-Dsun.security.spnego.debug=true Are you looking for more debug in that block that I've sent that you're not seeing?Suburban
@Michael-O, with those two jvm arguments set to true, there's not much else I see, unfortunately. I receive the following two lines on login attempt: providers.DocFinityAuthenticationProvider$KerberosProviderState (DocFinityAuthenticationProvider.java:630) - Authentication exception Kerberos validation not succesfull [0F4A2CA3D07F6ACB8571990AA85DA0F5] [10.10.1.154] ERROR [http-10.10.1.139-9080-1] providers.DocFinityAuthenticationProvider$ProviderState (DocFinityAuthenticationProvider.java:442) - Authentication exception: user is nullSuburban
My initial discovery of the GSS error RC4-HMAC message came through debugging in eclipse as a remote application... The error appears to be swallowed up by spring and converted to the Kerberos validation not successfull message!?!Suburban
There must be more output to stdout. See this thread for sample output.Conrado
Are you able to perform a kinit which that keytab?Conrado
@Conrado I just wanted to report back that I have not yet been able to get any more output to my logs or console. I'm still working on that.Suburban
As for kinit - this is a strange one (and maybe where I should be focusing more efforts?) I have received some successful runs there and have also produced encryption errors there as well. I'll run a clean test and report back some findings.Suburban
Keytab creation with 'echo on' shows me logging like: vno 12 etype 0x1 (DES-CBC-CRC) keylength 8 (0x67e0c2bf087a6264) vno 12 etype 0x3 (DES-CBC-MD5) keylength 8 (0x67e0c2bf087a6264) vno 12 etype 0x17 (RC4-HMAC) keylength 16 (0x781a482c1bff20be37b39869b437a11a) vno 12 etype 0x12 (AES256-SHA1) keylength 32 (0x1e1c35364aff4910f720e0e11f986fd3f4d35 vno 12 etype 0x11 (AES128-SHA1) keylength 16 (0x4cfa0f8a6cb59c762df60b2b52fd196f)Suburban
kinit -k -t c:\Users\http-key.keytab HTTP/[email protected] appears to work and grants me a new ticketSuburban
The keytab and kinit commands were run for my service user. Could it be that my service user is configured differently than my 'user' that is attempting to access my system? I don't believe that's how it works, but maybe there's something there I should look into? Should I try keytab and kinit with my 'user'?Suburban
For completeness - here is my keytab creation command: ktpass -out http-key.keytab -mapuser [email protected] -crypto All -princ HTTP/[email protected] -pass Test1ng -ptype KRB5_NT_PRINCIPALSuburban
Running the same keytab command and kinit command, replacing the server user with my personal user -- and everything still validates as expected and a new ticket is granted for me and stored in the cache.Suburban
Why do you use a keytab at all? You are running under Windows,let your JBoss run under the machine account and let the loginmodule access the ticket cache. Windows has the machine secret securely stored. This is the best you can do.Conrado
Did you actually use Wireshark to inspect the incoming ticket and the entire comm?Conrado
I used keytab because I thought I had to with the spring security model. We also support linux and I'm wondering if I use the jboss configuration, like you suggest, will that work with linux? I haven't looked into configuring it with Jboss at all as we've always used spring here. I did not inspect anything with wireshark. That can be next on my list unless you think I should give the jboss (non spring) configuration a shot first?Suburban
I have no experience with JBoss but that Spring extension is crap. I have written an extension which is far more versatile, I will release that during Christmas. Have you tried to setup a very basic spring project with SPNEGO auth? We are running SPNEGO auth on Unix with Java6 JGSS for years successfully. I can also provide a very simple test utility in Java in order to see your basic setup is ok w/o JBoss, Spring and stuff.Conrado
@Conrado - need a beta tester for that extension?!?!? I'll try to use Jboss' integration with kerberos today and see if I make any headway with that approach.Suburban
Thinking about this more... It still confuses me. Jboss/spring/etc... all of this is 'noise' in my opinion because the same keytab and everything works with the same code using JVM 6, but when using 7, it breaks. Did 7 introduce something that requires something differently to be done when generating the keytab or configuration somehow?Suburban
I'd be glad to have my code betatested by someone else. I have no exprience with Java 7 yet but I do not see any reason up until now why it should failed. I will share a simple example tomorrow for you to reproduce.Conrado
K
2

Yes! We patched SunJaasKerberosTicketValidator to look like this and it worked:

String keyTabPath = this.keyTabLocation.getURL().toExternalForm();
String runtimeVersion = System.getProperty("java.version");
if (runtimeVersion.startsWith("1.7")) 
{
      LOG.info("Detected jdk 7. Modifying keytabpath");
      if (keyTabPath != null)
      {
        if (keyTabPath.startsWith("file:")) 
        {
            keyTabPath = keyTabPath.substring(5);
        }
      }
}
LOG.info("KeyTabPath: " + keyTabPath);
LoginConfig loginConfig = new LoginConfig(keyTabPath, this.servicePrincipal,
                this.debug);
Killough answered 4/2, 2013 at 21:10 Comment(0)
O
1

Here are two potential issues that might be affecting you:

  1. Java 7 appears to switch the default encryption type order. Details:
  1. You did't say what specific version of JDK 7 you are using, but there was a bug in earlier versions of JDK 7 that prevented loading keytab files via "file:" URLs:

Another user on SO worked around the last issue by modifying Spring source:

Outstare answered 24/1, 2013 at 1:44 Comment(0)
D
1

Change the keyTabLocation object to a string.

So private String keyTabLocaiton.

      @Override
        public void afterPropertiesSet() throws Exception {
            Assert.notNull(this.servicePrincipal, "servicePrincipal must be specified");
            Assert.notNull(this.keyTabLocation, "keyTab must be specified");
            // if (keyTabLocation instanceof ClassPathResource) {
            // LOG.warn("Your keytab is in the classpath. This file needs special protection and shouldn't be in the classpath. JAAS may also not be able to load this file from classpath.");
            // }
            LoginConfig loginConfig = new LoginConfig(this.keyTabLocation, this.servicePrincipal,
                    this.debug);
            Set<Principal> princ = new HashSet<Principal>(1);
            princ.add(new KerberosPrincipal(this.servicePrincipal));
            Subject sub = new Subject(false, princ, new HashSet<Object>(), new HashSet<Object>());
            LoginContext lc = new LoginContext("", sub, null, loginConfig);
            lc.login();
            this.serviceSubject = lc.getSubject();
        }

Also where the LoginConfig guy, set the isInitiator flag to true.

 public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
            HashMap<String, String> options = new HashMap<String, String>();
            options.put("useKeyTab", "true");
            options.put("keyTab", this.keyTabLocation);
            options.put("principal", this.servicePrincipalName);
            options.put("storeKey", "true");
            options.put("doNotPrompt", "true");
            if (this.debug) {
                options.put("debug", "true");
            }
            options.put("isInitiator", "true");
            //options.put("isInitiator", "false");

            return new AppConfigurationEntry[] { new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
                    AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options), };
        }

Hopefully this helps you fix your issue.

Disbar answered 1/2, 2013 at 19:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.