Uploaded image for project: 'Hadoop Common'
  1. Hadoop Common
  2. HADOOP-16283

Error in reading Kerberos principals from the Keytab file

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: security
    • Labels:
      None

      Description

      The error refers to the launching of Namenode daemon when Kerberos is used for authentication. While reading Spnego principals (HTTP/.*) from the keytab file to start the Jetty server, KerberosUtil throws an error:

      javax.servlet.ServletException: java.io.IOException: Unexpected octets len: 16716
          at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.init(KerberosAuthenticationHandler.java:188)
          at org.apache.hadoop.security.authentication.server.AuthenticationFilter.initializeAuthHandler(AuthenticationFilter.java:194)
          at org.apache.hadoop.security.authentication.server.AuthenticationFilter.init(AuthenticationFilter.java:180)
          at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:139)
          at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:873)
          at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:349)
          at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1406)
          at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1368)
          at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778)
          at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262)
          at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:522)
          at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
          at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
          at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113)
          at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
          at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
          at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131)
          at org.eclipse.jetty.server.Server.start(Server.java:427)
          at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:105)
          at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
          at org.eclipse.jetty.server.Server.doStart(Server.java:394)
          at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
          at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:1140)
          at org.apache.hadoop.hdfs.server.namenode.NameNodeHttpServer.start(NameNodeHttpServer.java:177)
          at org.apache.hadoop.hdfs.server.namenode.NameNode.startHttpServer(NameNode.java:872)
          at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:694)
          at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:940)
          at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:913)
          at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1646)
          at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1713)
      Caused by: java.io.IOException: Unexpected octets len: 16716
          at org.apache.kerby.kerberos.kerb.KrbInputStream.readCountedOctets(KrbInputStream.java:72)
          at org.apache.kerby.kerberos.kerb.KrbInputStream.readKey(KrbInputStream.java:48)
          at org.apache.kerby.kerberos.kerb.keytab.KeytabEntry.load(KeytabEntry.java:55)
          at org.apache.kerby.kerberos.kerb.keytab.Keytab.readEntry(Keytab.java:203)
          at org.apache.kerby.kerberos.kerb.keytab.Keytab.readEntries(Keytab.java:189)
          at org.apache.kerby.kerberos.kerb.keytab.Keytab.doLoad(Keytab.java:161)
          at org.apache.kerby.kerberos.kerb.keytab.Keytab.load(Keytab.java:155)
          at org.apache.kerby.kerberos.kerb.keytab.Keytab.load(Keytab.java:143)
          at org.apache.kerby.kerberos.kerb.keytab.Keytab.loadKeytab(Keytab.java:55)
          at org.apache.hadoop.security.authentication.util.KerberosUtil.getPrincipalNames(KerberosUtil.java:225)
          at org.apache.hadoop.security.authentication.util.KerberosUtil.getPrincipalNames(KerberosUtil.java:244)
          at org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler.init(KerberosAuthenticationHandler.java:152)
          ... 29 more
      

        The main problem is with reading of keytab file generated by heimdal-kdc version 7.5.0. Keytab class of package org.apache.kerby.kerberos.kerb.keytab deals with reading entries from keytab file.

      This is the format of a keytab file.

      keytab {
            uint16_t file_format_version;                    # 0x502
            keytab_entry entries[*];
        };
      
        keytab_entry {
            int32_t size;
            uint16_t num_components;   # subtract 1 if version 0x501
            counted_octet_string realm;
            counted_octet_string components[num_components];
            uint32_t name_type;       # not present if version 0x501
            uint32_t timestamp;
            uint8_t vno8;
            keyblock key;
            uint32_t vno; #only present if >= 4 bytes left in entry
            uint32_t flags; #only present if >= 4 bytes left in entry
        };
      
        counted_octet_string {
            uint16_t length;
            uint8_t data[length];
        };
      
        keyblock {
            uint16_t type;
            counted_octet_string;
        };
      

      First field of keytab_entry is the size of this entry in bytes. This field itself is of four bytes. But, it contains the number of bytes of rest of the fields. Keytab class tries to calculate number of bytes read in every entry. The mistake is that it includes the (number of bytes of) first field in the calculation of total number of bytes read for a single entry. This leads to misinterpretation of successive entries in the keytab file. Hence, Unexpected Octet len error is thrown.

      I have raised an issue with apache/directory-kerby: https://issues.apache.org/jira/browse/DIRKRB-734.
      There is a PR also addressing this issue: https://github.com/apache/directory-kerby/pull/44

       

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                farhan5900 Farhan Khan
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated: