Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8080124

SPNEGO authentication broken

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 8u40, 8u45
    • security-libs

      FULL PRODUCT VERSION :
      Java SE 8 Update 45
      Java SE 8 Update 40

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.1.7601]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      the bug is most likely in the class library and not related anyhow to any specific platform (I could also reproduce the problem on Linux)

      A DESCRIPTION OF THE PROBLEM :
      SPNEGO authentication using JGSS is no longer working since Update 40. There were some changes in Kerberos related code in this release that was supposed to fix a bunch of bugs but unfortunately also broke things.

      REGRESSION. Last worked in version 8u31

      ADDITIONAL REGRESSION INFORMATION:
      standard Java SE 8 update 31 from download site

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a file krb5.conf in directory c:\tmp with the following content

      [libdefaults]
      default_keytab_name = FILE:C:/tmp/krb5.keytab
      default_realm = YOUR_DOMAIN

      Then create a kerberos keytab file and place it under c:\tmp\krb5.keytab

      The principal needs to be something like HTTP/fqdn@DOMAIN; I'm using AES256-CTS and have applied the unlimited strength JCE policy.

      Capture some kerberos ticket being sent as response to www-authenticate negotiate header that contains a kerberos ticket that is base64 encoded and then take out the header Authorization starting after the first occurrence of Negotiate.

      Use the source code below but before replace the string parameter to the method call decode in line 28 with the captured string.

      Then run the example code, which will come up with the provided output

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Entered SpNegoContext.acceptSecContext with state=STATE_NEW
      SpNegoContext.acceptSecContext: receiving token = ...
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.48018.1.2.2
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.113554.1.2.2
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.30
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.10
      SpNegoToken NegTokenInit: reading Mech Token
      SpNegoContext.acceptSecContext: received token of type = SPNEGO NegTokenInit
      SpNegoContext: negotiated mechanism = 1.2.840.113554.1.2.2
      SPNEGO Negotiated Mechanism = 1.2.840.113554.1.2.2 Kerberos V5
      SpNegoContext.acceptSecContext: mechanism wanted = 1.2.840.113554.1.2.2
      SpNegoContext.acceptSecContext: negotiated result = ACCEPT_COMPLETE
      SpNegoContext.acceptSecContext: sending token of type = SPNEGO NegTokenTarg
      SpNegoToken NegTokenTarg: sending additional token for MS Interop
      SpNegoContext.acceptSecContext: sending token = ...
      <user@DOMAIN>

      ACTUAL -
      Entered SpNegoContext.acceptSecContext with state=STATE_NEW
      SpNegoContext.acceptSecContext: receiving token = ...
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.48018.1.2.2
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.2.840.113554.1.2.2
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.30
      SpNegoToken NegTokenInit: reading Mechanism Oid = 1.3.6.1.4.1.311.2.2.10
      SpNegoToken NegTokenInit: reading Mech Token
      SpNegoContext.acceptSecContext: received token of type = SPNEGO NegTokenInit
      SpNegoContext: negotiated mechanism = 1.2.840.113554.1.2.2
      The underlying mechanism context has not been initialized
      SpNegoContext.acceptSecContext: mechanism wanted = 1.2.840.113554.1.2.2
      SpNegoContext.acceptSecContext: negotiated result = ACCEPT_INCOMPLETE
      SpNegoContext.acceptSecContext: sending token of type = SPNEGO NegTokenTarg
      SpNegoContext.acceptSecContext: sending token = ...
      Entered SpNegoContext.acceptSecContext with state=STATE_IN_PROCESS
      SpNegoContext.acceptSecContext: receiving token = ...
      SpNegoToken NegTokenTarg: negotiated result = Accept InComplete
      SpNegoToken NegTokenTarg: supported mechanism = 1.2.840.113554.1.2.2
      SpNegoContext.acceptSecContext: received token of type = SPNEGO NegTokenTarg
      Exception in thread "main" java.lang.NullPointerException
      at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.java:898)
      at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.java:623)
      at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:342)
      at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:285)
      at test.Test.main(Test.java:31)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package test;

      import java.util.Base64;

      import org.ietf.jgss.GSSContext;
      import org.ietf.jgss.GSSCredential;
      import org.ietf.jgss.GSSException;
      import org.ietf.jgss.GSSManager;
      import org.ietf.jgss.GSSName;
      import org.ietf.jgss.Oid;

      public class Test {

      public static void main(String[] args) throws GSSException {
      System.setProperty("java.security.krb5.conf", "C:/tmp/krb5.conf");
      System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
      System.setProperty("sun.security.spnego.debug", "true");

      GSSManager manager = GSSManager.getInstance();
      Oid oid = new Oid("1.3.6.1.5.5.2");
      GSSName name = manager.createName("HTTP/gentoo.asporc.waldvogel.name",null);
      GSSCredential credentials = manager.createCredential(name,GSSCredential.INDEFINITE_LIFETIME, oid,GSSCredential.ACCEPT_ONLY);
      GSSContext context = manager.createContext(credentials);

      if (context == null) {
      System.out.println("we have a problem");
      } else {
      byte[] token = Base64.getDecoder().decode("BASE64 encoded token as sent by the browser");

      while (!context.isEstablished()) {
      token = context.acceptSecContext(token, 0, token.length);
      }

      if (context.isEstablished()) {
      System.out.println(context.getSrcName().toString());
      } else {
      System.out.println("context not established");
      }
      }
      }

      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      I was able to get Update 40 and 45 working by patching rt.jar with class sun.security.jgss.spnego.SpNegoContext from Update 31.

            pardesha Pardeep Sharma
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: