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

JAAS does not lowercase the kerberos service name after DNS lookup

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • None
    • 1.4.0
    • security-libs



      Name: nt126004 Date: 10/14/2002


      FULL PRODUCT VERSION :
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta3-b84)
      Java HotSpot(TM) Client VM (build 1.4.0-beta3-b84, mixed mode)


      FULL OPERATING SYSTEM VERSION :

      SunOS zver 5.8 Generic_108528-09 sun4u sparc SUNW,Ultra-5_10

      A DESCRIPTION OF THE PROBLEM :
      A kerberos 5 service name is: service/hostname@realm
      GSSAPI RFC says that the "hostname" part is canonicalized by
      (i quote) attempting a DNS lookup and using the fully-
      qualified domain name which is returned, or by using the
      "hostname" as provided if the DNS lookup fails. The
      canonicalization operation also maps the host's name into
      lower-case characters. (end quote)

      I notice that JAAS does not lowercase what it gets from DNS,
      but uses it as-is. Therefore the kerberos service name in my
      case ends up as ldap/###@###.###
      and the KDC can't recognize it, since the principal is
      ldap/###@###.###. (ldap4.Stanford.EDU is
      the openldap 2.1.4 server, Kerberos 5 enabled)



      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      http://java.sun.com/products/jndi/tutorial/ldap/security/gssapi.html
      Use the JNDI GSSAPI example to connect to any ldap server
      using Kerberos5. If your DNS provides domain names in mixed
      case (as it is free to do - DNS is case insensitive) you
      will see this problem.


      EXPECTED VERSUS ACTUAL BEHAVIOR :

      ACTUAL RUN:
      --------------
      ATTENTION to the very last part, where it says

                  sname is ldap/ldap4.Stanford.EDU

      should say

                  sname is ldap/ldap4.stanford.edu

      java -Djava.security.auth.login.config=gss_open.conf
      -Djava.security.krb5.conf=/
      etc/leland/krb5.conf
      -Djava.security.krb5.kdc=krb5auth1.stanford.edu -Djava.secu
      rity.krb5.realm=stanford.edu -Dsun.security.krb5.debug=true
      GssExample

      Debug is true storeKey false useTicketCache false useKeyTab
      true doNotPrompt true ticketCache is null KeyTab is
      /etc/leland/keytab principal is host/zver.stanford.edu
      tryFirstPass is false useFirstPass is false storePass is
      false clearPass is false
      >>> KeyTab: load() entry length: 62
      >>> KeyTabInputStream, readName(): stanford.edu
      >>> KeyTabInputStream, readName(): host
      >>> KeyTabInputStream, readName(): zver.stanford.edu
      >>> KeyTab: load() entry length: 62
      >>> KeyTabInputStream, readName(): stanford.edu
      >>> KeyTabInputStream, readName(): ldap
      >>> KeyTabInputStream, readName(): zver.stanford.edu
      principal's key obtained from the keytab
      principal is host/###@###.###
      >>> EType: sun.security.krb5.internal.crypto.DesCbcCrcEType
      >>>crc32: ae79b06e
      >>>crc32: 10101110011110011011000001101110
      >>> KrbAsReq calling createMessage
      >>> KrbAsReq in createMessage
      >>> KrbAsReq etypes are: 3 1
      >>> KrbKdcReq send: kdc=krb5auth1.stanford.edu, port=88,
      timeout=30000, #bytes=236
      >>> KrbKdcReq send: #bytes read=533
      >>> EType: sun.security.krb5.internal.crypto.DesCbcMd5EType
      >>> KrbAsRep cons in KrbAsReq.getReply
      host/zver.stanford.edu
        Commit Succeeded

      >>> Credentials acquireServiceCreds: same realm
      >>> CksumType:
      sun.security.krb5.internal.crypto.RsaMd5CksumType
      >>> EType: sun.security.krb5.internal.crypto.DesCbcCrcEType
      >>>crc32: ad5c3147
      >>>crc32: 10101101010111000011000101000111
      >>> KrbKdcReq send: kdc=krb5auth1.stanford.edu, port=88,
      timeout=30000, #bytes=575
      >>> KrbKdcReq send: #bytes read=217
      >>> KDCRep: init() encoding tag is 126 req type is 13
      KrbException: Identifier doesn't match expected value (906)
              at sun.security.krb5.internal.aj.a(DashoA1275:125)
              at sun.security.krb5.internal.ai.a(DashoA1275:59)
              at
      sun.security.krb5.internal.ai.<init>(DashoA1275:54)
              at sun.security.krb5.KrbTgsRep.<init>(DashoA1275:43)
              at
      sun.security.krb5.KrbTgsReq.getReply(DashoA1275:221)
              at sun.security.krb5.internal.a4.a(DashoA1275:280)
              at sun.security.krb5.internal.a4.a(DashoA1275:94)
              at
      sun.security.krb5.Credentials.acquireServiceCreds(DashoA1275:550)
              at
      sun.security.jgss.krb5.Krb5Context.initSecContext(Krb5Context.java:507)
              at
      sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:216)
              at
      sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:161)
              at
      com.sun.security.sasl.gsskerb.GssKerberosV5.evaluateChallenge(GssKerberosV5.java:163)
              at
      com.sun.jndi.ldap.sasl.LdapSasl.saslBind(LdapSasl.java:116)

              at
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:42)
              at
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:28)
              at java.lang.reflect.Method.invoke(Method.java:327)
              at
      com.sun.jndi.ldap.LdapClient.saslBind(LdapClient.java:377)
              at
      com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:193)
              at
      com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2519)
              at
      com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:266)
              at
      com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:79)
              at
      javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:665)
              at
      javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:246)
              at
      javax.naming.InitialContext.init(InitialContext.java:222)
              at
      javax.naming.InitialContext.<init>(InitialContext.java:198)
              at
      javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:83)
              at
      JndiAction.performJndiOperation(GssExample.java:134)
              at JndiAction.run(GssExample.java:97)
              at
      java.security.AccessController.doPrivileged(Native Method)
              at
      javax.security.auth.Subject.doAs(Subject.java:321)
              at GssExample.main(GssExample.java:80)
      >>>KRBError:
                  cTime is Tue Sep 10 11:25:03 PDT 2002
      1031682303000
                  sTime is Tue Sep 10 11:25:04 PDT 2002
      1031682304000
                  suSec is 178369
                  error code is 7
                  crealm is stanford.edu
                  cname is host/zver.stanford.edu
                  realm is stanford.edu
                  sname is ldap/ldap4.Stanford.EDU
                  etext is Server not found in Kerberos database
      KrbException: Server not found in Kerberos database (7) -
      Server not found in Kerberos database


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Seen in the "Expected and Actual Results" field above.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      This is taken from your ldap security tutorial:
      http://java.sun.com/products/jndi/tutorial/ldap/security/gssapi.html

      GssExample.java:

      import javax.naming.*;
      import javax.naming.directory.*;
      import javax.security.auth.login.*;
      import javax.security.auth.Subject;

      import java.util.Hashtable;

      /**
       * Demonstrates how to create an initial context to an LDAP server
       * using "GSSAPI" SASL authentication (Kerberos v5).
       * Requires J2SE 1.4, or JNDI 1.2 with ldapbp.jar, JAAS, JCE, an RFC 2853
       * compliant implementation of J-GSS and a Kerberos v5 implementation.
       * Uses SampleCallbackHandler.
       *
       * usage: java
       * -Djava.security.auth.login.config=gssapi_jaas.conf * -Djava.security.krb5.conf=krb5.conf * GssExample [qop [dn]]
       *
       * The first property indicates which JAAS login module the application needs
       * to use; the second property is for configuration of the Kerberos subsystem.
       *
       * 'qop' is a comma separated list of tokens, each of which is one of
       * auth, auth-int, or auth-conf. If none is supplied, the default is 'auth'.
       */
      class GssExample {

          public static void main(String[] args) {

              // 1. Log in (to Kerberos)
              LoginContext lc = null;
              try {
                  lc = new LoginContext(GssExample.class.getName(),
                      new SampleCallbackHandler());

                  // Attempt authentication
                  // You might want to do this in a "for" loop to give
                  // user more than one chance to enter correct username/password
                  lc.login();

              } catch (LoginException le) {
                  System.err.println("Authentication attempt failed" + le);
                  System.exit(-1);
              }

              // 2. Perform JNDI work as logged in subject
              Subject.doAs(lc.getSubject(), new JndiAction(args));
          }
      }


      /**
       * The application must supply a PrivilegedAction that is to be run
       * inside a Subject.doAs() or Subject.doAsPrivileged().
       */
      class JndiAction implements java.security.PrivilegedAction {
          private String[] args;

          public JndiAction(String[] origArgs) {
              this.args = (String[])origArgs.clone();
          }

          public Object run() {
              performJndiOperation(args);
              return null;
          }

          private static void performJndiOperation(String[] args) {
              String dn;

              // Set up environment for creating initial context
              Hashtable env = new Hashtable(11);

              env.put(Context.INITIAL_CONTEXT_FACTORY,
                  "com.sun.jndi.ldap.LdapCtxFactory");

              // Must use fully qualified hostname
              env.put(Context.PROVIDER_URL,
                  "ldap://ldap4.stanford.edu:389");

          
              // Request the use of the "GSSAPI" SASL mechanism
              // Authenticate by using already established Kerberos credentials
              env.put(Context.SECURITY_AUTHENTICATION, "GSSAPI");

        env.put("javax.security.sasl.server.authentication", "true");

              // Optional first argument is comma-separated list of auth, auth-int,
              // auth-conf
              if (args.length > 0) {
                  env.put("javax.security.sasl.qop", args[0]);
                  dn = args[1];
              } else {
              dn = "";
              }
          
              try {
                  /* Create initial context */
                  DirContext ctx = new InitialDirContext(env);

                  System.out.println(ctx.getAttributes(dn));

                  // do something useful with ctx

                  // Close the context when we're done
                  ctx.close();
              } catch (NamingException e) {
                  e.printStackTrace();
              }
          }
      }



      Module conf file, gss_open.conf:

      GssExample {
        com.sun.security.auth.module.Krb5LoginModule required client=TRUE
      doNotPrompt=true debug=true useKeyTab=true keyTab="/etc/leland/keytab"
      principal="host/zver.stanford.edu";
      };



      krb5.conf:

      # krb5.conf -- Kerberos V5 general configuration.
      # $Id: krb5.conf,v 1.6 2001/06/09 06:15:09 eagle Exp $
      #
      # This is Stanford's site-wide default Kerberos V5 configuration file. It
      # is maintained by ###@###.###; if there are other realms
      # and/or realm mappings that you use on a regular basis and would like to
      # see added to this file, please contact the above address.

      [appdefaults]
          aklog_path = /etc/leland/aklog
          default_lifetime = 25hrs
          krb4_get_tickets = false
          krb5_get_tickets = true
          krb5_get_forwardable = true
          krb_run_aklog = false

          kinit = {
              krb4_convert = false
          }

          stanford.edu = {
              krb4_get_tickets = true
              krb4_convert = false
              krb_run_aklog = true
          }

      [libdefaults]
          default_realm = stanford.edu
          default_tgs_enctypes = des-cbc-crc
          default_tkt_enctypes = des-cbc-crc
          krb4_config = /etc/leland/krb.conf
          krb4_realms = /etc/leland/krb.realms
          kdc_req_checksum_type = 2
          ap_req_checksum_type = 2
          safe_checksum_type = 3
          ccache_type = 2

      [realms]
          stanford.edu = {
              kdc = krb5auth1.stanford.edu:88
              kdc = krb5auth2.stanford.edu:88
              kdc = krb5auth3.stanford.edu:88
              admin_server = krb5-admin.stanford.edu
              default_domain = stanford.edu
              v4_realm = IR.STANFORD.EDU
          }
          VIX.COM = {
              kdc = kerberos-0.vix.com:88
              kdc = kerberos-1.vix.com:88
              kdc = kerberos-2.vix.com:88
              admin_server = kerberos-0.vix.com:749
              default_domain = vix.com
          }
              MS.STANFORD.EDU = {
                      kdc=msdc0.ms.stanford.edu:88
                      kdc=msdc1.ms.stanford.edu:88
                      
              }

      [domain_realm]
          stanford.edu = stanford.edu
          .stanford.edu = stanford.edu
          .dc.stanford.org = stanford.edu
          .vix.com = VIX.COM
          .ms.stanford.edu = MS.STANFORD.EDU
           ms.stanford.edu = MS.STANFORD.EDU

      [logging]
          kdc = SYSLOG:NOTICE
          admin_server = SYSLOG:NOTICE
          default = SYSLOG:NOTICE

      ---------- END SOURCE ----------

      CUSTOMER WORKAROUND :
      if the /etc/hosts file is outfitted with a line translating
      the IP address to the explicitly lowercase hostname of the
      ldap server, everything works fine. But it's lame to have to
      require that of users. Especially on other platforms like
      Windows.
      (Review ID: 164305)
      ======================================================================

            rmartisunw Ramachandran Marti (Inactive)
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: