code review request: 6979329: CCacheInputStream fails to read ticket cache files from Kerberos 1.8.1

Weijun Wang Weijun.Wang at Sun.COM
Tue Aug 24 01:06:18 PDT 2010


HI All

webrev at --

   http://cr.openjdk.java.net/~weijun/6979329/webrev.00/

I'm not sure if there will be other type of non-ticket entries later, so 
just ignore once an exception is thrown.

I'll be glad if there can be more than one code reviewers. Mostly likely 
this will need to backported to update releases of JDK 6.

Thanks
Max

-------- Original Message --------

*Change Request ID*: 6979329
*Synopsis*: CCacheInputStream fails to read ticket cache files from 
Kerberos 1.8.1


=== *Description* 
============================================================
FULL PRODUCT VERSION :
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux thomas 2.6.32-24-generic #39-Ubuntu SMP Wed Jul 28 05:14:15 UTC 
2010 x86_64 GNU/Linux

EXTRA RELEVANT SYSTEM CONFIGURATION :
Kerberos 1.8.1

A DESCRIPTION OF THE PROBLEM :
Kerberos 1.8.1 introduced a new feature by which configuration settings 
can be stored in the ticket cache file using a special principal name:
http://krbdev.mit.edu/rt/Ticket/Display.html?user=guest&pass=guest&id=6206

This breaks CCacheInputStream in such a way that the entire ticket cache 
file is unreadable.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
- Install Kerberos 1.8.1 or later
- kinit
- strings /path/to/ticketcache | grep X-CACHE
If X-CACHE is in the file, then the Krb5Login module will not be able to 
make use of the cache.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Ticket cache is parsed correctly with new-style configuration 
credentials ignored.
ACTUAL -
Ticket cache fails to load. Debug output shows an exception trying to 
parse the configuration variable "yes" as if it were an encrypted ticket.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
>>>DEBUG <CCacheInputStream>  client principal is atm at ATM-LOCAL
>>>DEBUG <CCacheInputStream> server principal is X-CACHECONF:/krb5_ccache_conf_data/fast_avail/krbtgt/ATM-LOCAL at ATM-LOCAL
>>>DEBUG <CCacheInputStream> key type: 0
>>>DEBUG <CCacheInputStream> auth time: Wed Dec 31 16:00:00 PST 1969
>>>DEBUG <CCacheInputStream> start time: Wed Dec 31 16:00:00 PST 1969
>>>DEBUG <CCacheInputStream> end time: Wed Dec 31 16:00:00 PST 1969
>>>DEBUG <CCacheInputStream> renew_till time: Wed Dec 31 16:00:00 PST 1969
>>> CCacheInputStream: readFlags()
java.io.IOException: extra data given to DerValue constructor
         at sun.security.util.DerValue.init(DerValue.java:368)
         at sun.security.util.DerValue.<init>(DerValue.java:277)
         at sun.security.krb5.internal.Ticket.<init>(Ticket.java:81)
         at 
sun.security.krb5.internal.ccache.CCacheInputStream.readData(CCacheInputStream.java:250)
         at 
sun.security.krb5.internal.ccache.CCacheInputStream.readCred(CCacheInputStream.java:357)
         at 
sun.security.krb5.internal.ccache.FileCredentialsCache.load(FileCredentialsCache.java:225)
         at 
sun.security.krb5.internal.ccache.FileCredentialsCache.acquireInstance(FileCredentialsCache.java:104)
         at 
sun.security.krb5.internal.ccache.CredentialsCache.getInstance(CredentialsCache.java:75)
         at 
sun.security.krb5.Credentials.acquireTGTFromCache(Credentials.java:309)
         at 
com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:589)
         at 
com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
On Kerberos 1.8.1, renewing the local kerberos ticket with "kinit -R" 
drops the special configuration credential initially added by "kinit", 
allowing this to succeed.

The following patch resolves the problem:

diff -r krb5.orig/internal/ccache/CCacheInputStream.java 
krb5.new/internal/ccache/CCacheInputStream.java
362a363,367
>         if (isConfigurationPrincipal(spname)) {
>             skipLengthPrefixedData(); // skip ticket
>             skipLengthPrefixedData(); // skip secondary ticket
>             return null;
>         }
375a381,400
>
>     /**
>      * Return true if the given principal corresponds to a non-ticket configuration
>      * entry in the cache file.
>      */
>     private boolean isConfigurationPrincipal(PrincipalName princ) {
>         String[] components = princ.getNameStrings();
>         return (components.length > 2 &&
>             PrincipalName.CONFIGURATION_REALM.equals(components[0]) &&
>             PrincipalName.CONFIGURATION_NAME.equals(components[1]));
>     }
>
>     /**
>      * Read a 32-bit length from the stream and skip an equal number of bytes.
>      */
>     private void skipLengthPrefixedData() throws IOException {
>         int skip = read(4);
>         byte[] skipbuf = new byte[skip];
>         read(skipbuf, 0, skip);
>     }
diff -r krb5.orig/internal/ccache/FileCredentialsCache.java 
krb5.new/internal/ccache/FileCredentialsCache.java
189c189,192
<             credentialsList.addElement(cis.readCred(version));
---
>             Credentials cred = cis.readCred(version);
>             if (cred != null) {
>                 credentialsList.addElement(cred);
>             }
diff -r krb5.orig/PrincipalName.java krb5.new/PrincipalName.java
89a90,99
>     /**
>      * The realm used for non-ticket configuration data stored in ccache
>      */
>     public static final String CONFIGURATION_REALM = "X-CACHECONF:";
>
>     /**
>      * The nameused for non-ticket configuration data stored in ccache
>      */
>     public static final String CONFIGURATION_NAME = "krb5_ccache_conf_data";
>

*** (#1 of 1): 2010-08-24 01:26:27 GMT+00:00 weijun.wang at sun.com



More information about the security-dev mailing list